From 6f2dfa09eae6814e61008f6764e7cda49968b84a Mon Sep 17 00:00:00 2001 From: Evelyn Tanigawa Murasaki Date: Mon, 27 Apr 2026 14:51:31 -0300 Subject: [PATCH 1/3] perses and monitoring stabilization --- web/cypress/e2e/monitoring/00.bvt_admin.cy.ts | 4 + .../e2e/perses/00.coo_bvt_perses_admin.cy.ts | 1 + .../perses/04.coo_import_perses_admin.cy.ts | 1 + .../e2e/perses/99.coo_rbac_perses_user1.cy.ts | 3 + .../e2e/perses/99.coo_rbac_perses_user2.cy.ts | 2 + .../e2e/perses/99.coo_rbac_perses_user3.cy.ts | 3 + .../e2e/perses/99.coo_rbac_perses_user4.cy.ts | 3 + .../e2e/perses/99.coo_rbac_perses_user5.cy.ts | 3 + .../e2e/perses/99.coo_rbac_perses_user6.cy.ts | 2 + .../import/testing-perses-dashboard.json | 36 +----- .../import/testing-perses-dashboard.yaml | 23 +--- web/cypress/fixtures/perses/constants.ts | 15 +-- .../support/commands/dashboards-commands.ts | 113 +++++------------- .../support/commands/utility-commands.ts | 48 ++++---- .../monitoring/00.bvt_monitoring.cy.ts | 4 +- .../monitoring/03.reg_legacy_dashboards.cy.ts | 5 - .../06.reg_legacy_dashboards_namespace.cy.ts | 4 - .../perses/01.coo_list_perses_admin.cy.ts | 2 +- .../perses/03.coo_create_perses_admin.cy.ts | 2 +- .../perses/04.coo_import_perses_admin.cy.ts | 2 - .../perses/99.coo_rbac_perses_user1.cy.ts | 8 +- web/cypress/views/alerting-rule-list-page.ts | 21 +++- web/cypress/views/common.ts | 4 +- web/cypress/views/metrics.ts | 2 +- .../perses-dashboards-create-dashboard.ts | 28 ++++- .../views/perses-dashboards-edit-variables.ts | 1 + .../perses-dashboards-list-dashboards.ts | 4 +- web/cypress/views/perses-dashboards-panel.ts | 12 -- web/cypress/views/perses-dashboards.ts | 1 + web/cypress/views/silence-alert-page.ts | 2 +- web/src/components/data-test.ts | 4 +- 31 files changed, 156 insertions(+), 207 deletions(-) diff --git a/web/cypress/e2e/monitoring/00.bvt_admin.cy.ts b/web/cypress/e2e/monitoring/00.bvt_admin.cy.ts index b082cab6b..2ab6d9698 100644 --- a/web/cypress/e2e/monitoring/00.bvt_admin.cy.ts +++ b/web/cypress/e2e/monitoring/00.bvt_admin.cy.ts @@ -15,6 +15,8 @@ describe('BVT: Monitoring', { tags: ['@smoke', '@monitoring'] }, () => { }); beforeEach(() => { + nav.sidenav.clickNavLink(['Observe', 'Metrics']); + //TODO: remove this double Metrics click after the issue is fixed nav.sidenav.clickNavLink(['Observe', 'Metrics']); commonPages.titleShouldHaveText('Metrics'); cy.changeNamespace('All Projects'); @@ -36,6 +38,8 @@ describe('BVT: Monitoring', { tags: ['@smoke', '@monitoring'] }, () => { nav.sidenav.clickNavLink(['Observe', 'Dashboards']); commonPages.titleShouldHaveText('Dashboards'); nav.sidenav.clickNavLink(['Observe', 'Targets']); + //TODO: remove this double Targets click after the issue is fixed + nav.sidenav.clickNavLink(['Observe', 'Targets']); commonPages.titleShouldHaveText('Metrics targets'); }); // TODO: Intercept Bell GET request to inject an alert (Watchdog to have it opened in diff --git a/web/cypress/e2e/perses/00.coo_bvt_perses_admin.cy.ts b/web/cypress/e2e/perses/00.coo_bvt_perses_admin.cy.ts index 0968e050c..e51f3c241 100644 --- a/web/cypress/e2e/perses/00.coo_bvt_perses_admin.cy.ts +++ b/web/cypress/e2e/perses/00.coo_bvt_perses_admin.cy.ts @@ -30,6 +30,7 @@ describe( beforeEach(() => { nav.sidenav.clickNavLink(['Observe', 'Dashboards (Perses)']); + cy.changeNamespace('All Projects'); }); //TODO: rename after customizable-dashboards gets merged diff --git a/web/cypress/e2e/perses/04.coo_import_perses_admin.cy.ts b/web/cypress/e2e/perses/04.coo_import_perses_admin.cy.ts index 94bb852dd..e49001030 100644 --- a/web/cypress/e2e/perses/04.coo_import_perses_admin.cy.ts +++ b/web/cypress/e2e/perses/04.coo_import_perses_admin.cy.ts @@ -30,6 +30,7 @@ describe( beforeEach(() => { nav.sidenav.clickNavLink(['Observe', 'Dashboards']); + cy.wait(2000); nav.sidenav.clickNavLink(['Observe', 'Dashboards (Perses)']); cy.wait(5000); cy.changeNamespace('All Projects'); diff --git a/web/cypress/e2e/perses/99.coo_rbac_perses_user1.cy.ts b/web/cypress/e2e/perses/99.coo_rbac_perses_user1.cy.ts index 1d04fc675..252a89577 100644 --- a/web/cypress/e2e/perses/99.coo_rbac_perses_user1.cy.ts +++ b/web/cypress/e2e/perses/99.coo_rbac_perses_user1.cy.ts @@ -32,6 +32,7 @@ describe( // Step 2: Setup COO and Perses dashboards (requires admin privileges) cy.beforeBlockCOO(MCP, MP, { dashboards: true, troubleshootingPanel: false }); + cy.cleanupPersesTestDashboardsBeforeTests(); cy.setupPersesRBACandExtraDashboards(); //TODO: https://issues.redhat.com/browse/OCPBUGS-58468 - when it gets fixed, installation can be don using non-admin user @@ -68,7 +69,9 @@ describe( beforeEach(() => { nav.sidenav.clickNavLink(['Observe', 'Dashboards']); + cy.wait(2000); nav.sidenav.clickNavLink(['Observe', 'Dashboards (Perses)']); + cy.changeNamespace('All Projects'); }); after(() => { diff --git a/web/cypress/e2e/perses/99.coo_rbac_perses_user2.cy.ts b/web/cypress/e2e/perses/99.coo_rbac_perses_user2.cy.ts index f674be327..df7841491 100644 --- a/web/cypress/e2e/perses/99.coo_rbac_perses_user2.cy.ts +++ b/web/cypress/e2e/perses/99.coo_rbac_perses_user2.cy.ts @@ -32,6 +32,7 @@ describe( // Step 2: Setup COO and Perses dashboards (requires admin privileges) cy.beforeBlockCOO(MCP, MP, { dashboards: true, troubleshootingPanel: false }); + cy.cleanupPersesTestDashboardsBeforeTests(); cy.setupPersesRBACandExtraDashboards(); //TODO: https://issues.redhat.com/browse/OCPBUGS-58468 - when it gets fixed, installation can be don using non-admin user @@ -68,6 +69,7 @@ describe( beforeEach(() => { nav.sidenav.clickNavLink(['Observe', 'Dashboards']); + cy.wait(2000); nav.sidenav.clickNavLink(['Observe', 'Dashboards (Perses)']); cy.changeNamespace('All Projects'); }); diff --git a/web/cypress/e2e/perses/99.coo_rbac_perses_user3.cy.ts b/web/cypress/e2e/perses/99.coo_rbac_perses_user3.cy.ts index d95ac1be0..8e3532d10 100644 --- a/web/cypress/e2e/perses/99.coo_rbac_perses_user3.cy.ts +++ b/web/cypress/e2e/perses/99.coo_rbac_perses_user3.cy.ts @@ -32,6 +32,7 @@ describe( // Step 2: Setup COO and Perses dashboards (requires admin privileges) cy.beforeBlockCOO(MCP, MP, { dashboards: true, troubleshootingPanel: false }); + cy.cleanupPersesTestDashboardsBeforeTests(); cy.setupPersesRBACandExtraDashboards(); //TODO: https://issues.redhat.com/browse/OCPBUGS-58468 - when it gets fixed, installation can be don using non-admin user @@ -68,7 +69,9 @@ describe( beforeEach(() => { nav.sidenav.clickNavLink(['Observe', 'Dashboards']); + cy.wait(2000); nav.sidenav.clickNavLink(['Observe', 'Dashboards (Perses)']); + cy.changeNamespace('All Projects'); }); after(() => { diff --git a/web/cypress/e2e/perses/99.coo_rbac_perses_user4.cy.ts b/web/cypress/e2e/perses/99.coo_rbac_perses_user4.cy.ts index 6f84db67b..4e296fffc 100644 --- a/web/cypress/e2e/perses/99.coo_rbac_perses_user4.cy.ts +++ b/web/cypress/e2e/perses/99.coo_rbac_perses_user4.cy.ts @@ -32,6 +32,7 @@ describe( // Step 2: Setup COO and Perses dashboards (requires admin privileges) cy.beforeBlockCOO(MCP, MP, { dashboards: true, troubleshootingPanel: false }); + cy.cleanupPersesTestDashboardsBeforeTests(); cy.setupPersesRBACandExtraDashboards(); //TODO: https://issues.redhat.com/browse/OCPBUGS-58468 - when it gets fixed, installation can be don using non-admin user @@ -68,7 +69,9 @@ describe( beforeEach(() => { nav.sidenav.clickNavLink(['Observe', 'Dashboards']); + cy.wait(2000); nav.sidenav.clickNavLink(['Observe', 'Dashboards (Perses)']); + cy.changeNamespace('All Projects'); }); after(() => { diff --git a/web/cypress/e2e/perses/99.coo_rbac_perses_user5.cy.ts b/web/cypress/e2e/perses/99.coo_rbac_perses_user5.cy.ts index 90596c576..94e9ada81 100644 --- a/web/cypress/e2e/perses/99.coo_rbac_perses_user5.cy.ts +++ b/web/cypress/e2e/perses/99.coo_rbac_perses_user5.cy.ts @@ -32,6 +32,7 @@ describe( // Step 2: Setup COO and Perses dashboards (requires admin privileges) cy.beforeBlockCOO(MCP, MP, { dashboards: true, troubleshootingPanel: false }); + cy.cleanupPersesTestDashboardsBeforeTests(); cy.setupPersesRBACandExtraDashboards(); //TODO: https://issues.redhat.com/browse/OCPBUGS-58468 - when it gets fixed, installation can be don using non-admin user @@ -68,7 +69,9 @@ describe( beforeEach(() => { nav.sidenav.clickNavLink(['Observe', 'Dashboards']); + cy.wait(2000); nav.sidenav.clickNavLink(['Observe', 'Dashboards (Perses)']); + cy.changeNamespace('All Projects'); }); after(() => { diff --git a/web/cypress/e2e/perses/99.coo_rbac_perses_user6.cy.ts b/web/cypress/e2e/perses/99.coo_rbac_perses_user6.cy.ts index 0b37438e3..4680bc1a3 100644 --- a/web/cypress/e2e/perses/99.coo_rbac_perses_user6.cy.ts +++ b/web/cypress/e2e/perses/99.coo_rbac_perses_user6.cy.ts @@ -32,6 +32,7 @@ describe( // Step 2: Setup COO and Perses dashboards (requires admin privileges) cy.beforeBlockCOO(MCP, MP, { dashboards: true, troubleshootingPanel: false }); + cy.cleanupPersesTestDashboardsBeforeTests(); cy.setupPersesRBACandExtraDashboards(); //TODO: https://issues.redhat.com/browse/OCPBUGS-58468 - when it gets fixed, installation can be don using non-admin user @@ -68,6 +69,7 @@ describe( beforeEach(() => { nav.sidenav.clickNavLink(['Observe', 'Dashboards']); + cy.wait(2000); nav.sidenav.clickNavLink(['Observe', 'Dashboards (Perses)']); }); diff --git a/web/cypress/fixtures/coo/coo140_perses/import/testing-perses-dashboard.json b/web/cypress/fixtures/coo/coo140_perses/import/testing-perses-dashboard.json index 5a0099cb2..f5a2059af 100644 --- a/web/cypress/fixtures/coo/coo140_perses/import/testing-perses-dashboard.json +++ b/web/cypress/fixtures/coo/coo140_perses/import/testing-perses-dashboard.json @@ -231,31 +231,6 @@ } ] } - }, - "c03e17f849d341bcb1139c65e68dad1d": { - "kind": "Panel", - "spec": { - "display": { - "name": "status history" - }, - "plugin": { - "kind": "StatusHistoryChart", - "spec": {} - }, - "queries": [ - { - "kind": "TimeSeriesQuery", - "spec": { - "plugin": { - "kind": "PrometheusTimeSeriesQuery", - "spec": { - "query": "vector(1)" - } - } - } - } - ] - } } }, "layouts": [ @@ -317,16 +292,7 @@ { "x": 0, "y": 15, - "width": 12, - "height": 6, - "content": { - "$ref": "#/spec/panels/c03e17f849d341bcb1139c65e68dad1d" - } - }, - { - "x": 12, - "y": 15, - "width": 12, + "width": 24, "height": 6, "content": { "$ref": "#/spec/panels/31b8374866184a26beddf46ec30df0b5" diff --git a/web/cypress/fixtures/coo/coo140_perses/import/testing-perses-dashboard.yaml b/web/cypress/fixtures/coo/coo140_perses/import/testing-perses-dashboard.yaml index ef5cd77e2..5fb97a105 100644 --- a/web/cypress/fixtures/coo/coo140_perses/import/testing-perses-dashboard.yaml +++ b/web/cypress/fixtures/coo/coo140_perses/import/testing-perses-dashboard.yaml @@ -143,21 +143,6 @@ spec: kind: PrometheusTimeSeriesQuery spec: query: up - c03e17f849d341bcb1139c65e68dad1d: - kind: Panel - spec: - display: - name: status history - plugin: - kind: StatusHistoryChart - spec: {} - queries: - - kind: TimeSeriesQuery - spec: - plugin: - kind: PrometheusTimeSeriesQuery - spec: - query: vector(1) layouts: - kind: Grid spec: @@ -198,13 +183,7 @@ spec: $ref: "#/spec/panels/57ce686052c9464fa9486ff49d3757cd" - x: 0 "y": 15 - width: 12 - height: 6 - content: - $ref: "#/spec/panels/c03e17f849d341bcb1139c65e68dad1d" - - x: 12 - "y": 15 - width: 12 + width: 24 height: 6 content: $ref: "#/spec/panels/31b8374866184a26beddf46ec30df0b5" diff --git a/web/cypress/fixtures/perses/constants.ts b/web/cypress/fixtures/perses/constants.ts index 2a7ff2fa6..a9a77ea4d 100644 --- a/web/cypress/fixtures/perses/constants.ts +++ b/web/cypress/fixtures/perses/constants.ts @@ -142,12 +142,12 @@ export const persesDashboardsAddPanelAddQueryType = { }; export const persesCreateDashboard = { - DIALOG_MAX_LENGTH_VALIDATION: 'Must be 75 or fewer characters long: error status;', + DIALOG_MAX_LENGTH_VALIDATION: + 'Danger alert:bad request: code=400, message=cannot contain more than 75 characters, internal=cannot contain more than 75 characters', DIALOG_DUPLICATED_NAME_PF_VALIDATION_PREFIX: 'Dashboard name ', DIALOG_DUPLICATED_NAME_PF_VALIDATION_SUFFIX: ' already exists in ', DIALOG_DUPLICATED_NAME_PF_VALIDATION_SUFFIX_PROJECT: ' project!: error status;', - DIALOG_DUPLICATED_NAME_BKD_VALIDATION: - 'Danger alert:Could not create dashboard. e: document already exists', + DIALOG_CREATE_NAME_BKD_VALIDATION: 'Danger alert:document already exists', }; export const persesDashboardsEmptyDashboard = { @@ -167,7 +167,9 @@ export const persesDashboardsRenameDashboard = { }; export const persesDashboardsDuplicateDashboard = { - DIALOG_DUPLICATED_NAME_VALIDATION: 'already exists', //use contains + DIALOG_DUPLICATED_NAME_VALIDATION: 'Could not duplicate dashboard. e: document already exists', //use contains + DIALOG_DUPLICATED_NAME_FED_VALIDATION_1: 'Dashboard name "', + DIALOG_DUPLICATED_NAME_FED_VALIDATION_2: '" already exists in this project: error status;', }; export const persesDashboardsImportDashboard = { @@ -180,7 +182,6 @@ export const persesDashboardsImportDashboard = { 'Grafana dashboard detected. It will be automatically migrated to Perses format. Note: migration may be partial as not all Grafana features are supported.', DIALOG_PERSES_DASHBOARD_DETECTED: 'Perses dashboard detected.', DIALOG_FAILED_TO_MIGRATE_GRAFANA_DASHBOARD: - 'Danger alert:Error migrating dashboard: Failed to migrate dashboard: internal server error', - DIALOG_DUPLICATED_DASHBOARD_ERROR: - 'Danger alert:Error importing dashboard: document already exists', + 'Danger alert:Failed to migrate dashboard: internal server error', + DIALOG_DUPLICATED_DASHBOARD_ERROR: 'Danger alert:document already exists', }; diff --git a/web/cypress/support/commands/dashboards-commands.ts b/web/cypress/support/commands/dashboards-commands.ts index 4c7f2496a..407fc86eb 100644 --- a/web/cypress/support/commands/dashboards-commands.ts +++ b/web/cypress/support/commands/dashboards-commands.ts @@ -30,92 +30,45 @@ export const dashboardsUtils = { failOnNonZeroExit: false, }); - /** - * TODO: When COO1.4.0 is released, points COO_UI_INSTALL to install dashboards on - * COO1.4.0 folder - */ - if (Cypress.env('COO_UI_INSTALL')) { - cy.log('COO_UI_INSTALL is set. Installing dashboards on COO1.4.0 folder'); - - cy.log('Create openshift-cluster-sample-dashboard instance.'); - cy.exec( - `oc apply -f ./cypress/fixtures/coo/coo140_perses/dashboards/` + - `openshift-cluster-sample-dashboard.yaml ` + - `--kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, - ); - - cy.log('Create perses-dashboard-sample instance.'); - cy.exec( - `oc apply -f ./cypress/fixtures/coo/coo140_perses/dashboards/` + - `perses-dashboard-sample.yaml ` + - `--kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, - ); - - cy.log('Create prometheus-overview-variables instance.'); - cy.exec( - `oc apply -f ./cypress/fixtures/coo/coo140_perses/dashboards/` + - `prometheus-overview-variables.yaml ` + - `--kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, - ); - - cy.log('Create thanos-compact-overview-1var instance.'); - cy.exec( - `oc apply -f ./cypress/fixtures/coo/coo140_perses/dashboards/` + - `thanos-compact-overview-1var.yaml ` + - `--kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, - ); - - cy.log('Create Thanos Querier instance.'); - cy.exec( - `oc apply -f ./cypress/fixtures/coo/coo140_perses/dashboards/` + - `thanos-querier-datasource.yaml ` + - `--kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, - ); - } else { - cy.log('COO_UI_INSTALL is not set. Installing dashboards on COO1.4.0 folder'); - - cy.log('Create openshift-cluster-sample-dashboard instance.'); - cy.exec( - `oc apply -f ./cypress/fixtures/coo/coo140_perses/dashboards/` + - `openshift-cluster-sample-dashboard.yaml ` + - `--kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, - ); + cy.log('Create openshift-cluster-sample-dashboard instance.'); + cy.exec( + `oc apply -f ./cypress/fixtures/coo/coo140_perses/dashboards/` + + `openshift-cluster-sample-dashboard.yaml ` + + `--kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, + ); - cy.log('Create perses-dashboard-sample instance.'); - cy.exec( - `oc apply -f ./cypress/fixtures/coo/coo140_perses/dashboards/` + - `perses-dashboard-sample.yaml ` + - `--kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, - ); + cy.log('Create perses-dashboard-sample instance.'); + cy.exec( + `oc apply -f ./cypress/fixtures/coo/coo140_perses/dashboards/` + + `perses-dashboard-sample.yaml ` + + `--kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, + ); - cy.log('Create prometheus-overview-variables instance.'); - cy.exec( - `oc apply -f ./cypress/fixtures/coo/coo140_perses/dashboards/` + - `prometheus-overview-variables.yaml ` + - `--kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, - ); + cy.log('Create prometheus-overview-variables instance.'); + cy.exec( + `oc apply -f ./cypress/fixtures/coo/coo140_perses/dashboards/` + + `prometheus-overview-variables.yaml ` + + `--kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, + ); - cy.log('Create thanos-compact-overview-1var instance.'); - cy.exec( - `oc apply -f ./cypress/fixtures/coo/coo140_perses/dashboards/` + - `thanos-compact-overview-1var.yaml ` + - `--kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, - ); + cy.log('Create thanos-compact-overview-1var instance.'); + cy.exec( + `oc apply -f ./cypress/fixtures/coo/coo140_perses/dashboards/` + + `thanos-compact-overview-1var.yaml ` + + `--kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, + ); - cy.log('Create Thanos Querier instance.'); - cy.exec( - `oc apply -f ./cypress/fixtures/coo/coo140_perses/dashboards/` + - `thanos-querier-datasource.yaml ` + - `--kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, - ); - } + cy.log('Create Thanos Querier instance.'); + cy.exec( + `oc apply -f ./cypress/fixtures/coo/coo140_perses/dashboards/` + + `thanos-querier-datasource.yaml ` + + `--kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, + ); cy.exec( - `oc label namespace ${ - MCP.namespace - } openshift.io/cluster-monitoring=true --overwrite=true --kubeconfig ${Cypress.env( - 'KUBECONFIG_PATH', - )}`, + `oc label namespace ${MCP.namespace} ` + + `openshift.io/cluster-monitoring=true --overwrite=true ` + + `--kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, ); waitForPodsReady( diff --git a/web/cypress/support/commands/utility-commands.ts b/web/cypress/support/commands/utility-commands.ts index 8759a8b17..5a1bb7cf8 100644 --- a/web/cypress/support/commands/utility-commands.ts +++ b/web/cypress/support/commands/utility-commands.ts @@ -57,7 +57,6 @@ Cypress.Commands.add('clickNavLink', (path: string[]) => { Cypress.Commands.add('changeNamespace', (namespace: string) => { cy.log('Changing Namespace to: ' + namespace); - cy.wait(2000); cy.get('body').then(($body) => { const hasNamespaceBarDropdown = $body.find('[data-test-id="' + LegacyTestIDs.NamespaceBarDropdown + '"]').length > 0; @@ -141,31 +140,41 @@ Cypress.Commands.overwrite('log', (log, ...args) => { Cypress.Commands.add('podImage', (pod: string, namespace: string) => { cy.log('Get pod image'); cy.switchPerspective('Core platform', 'Administrator'); - cy.wait(5000); cy.clickNavLink(['Workloads', 'Pods']); - cy.changeNamespace(namespace); cy.byTestID('page-heading').contains('Pods').should('be.visible'); - cy.wait(5000); - // Check for DataViewFilters component using Cypress's built-in retry-ability + cy.changeNamespace(namespace); + // Wait for the pod table to load after namespace change so the page stabilizes + cy.get('table tbody tr, [data-ouia-component-id="DataViewTable"] tbody tr', { + timeout: 30000, + }).should('have.length.greaterThan', 0); + // Re-check for DataViewFilters after the table has stabilized cy.get('body').then(($body) => { const hasDataViewFilters = $body.find('[data-ouia-component-id="DataViewFilters"]').length > 0; + let filterSelector: string; if (hasDataViewFilters) { - cy.byOUIAID('DataViewFilters') - .find('button') - .contains('Status') - .scrollIntoView() - .should('be.visible') - .click(); - cy.byOUIAID('OUIA-Generated-Menu') - .find('button') - .contains('Name') - .scrollIntoView() - .should('be.visible') - .click(); - cy.get('[placeholder="Filter by name"]').scrollIntoView().should('be.visible').type(pod); + const hasFilterByName = $body.find('[placeholder="Filter by name"]').length > 0; + filterSelector = '[placeholder="Filter by name"]'; + if (!hasFilterByName) { + cy.byOUIAID('DataViewFilters') + .find('button') + .contains('Status') + .scrollIntoView() + .should('be.visible') + .click(); + cy.byOUIAID('OUIA-Generated-Menu') + .find('button') + .contains('Name') + .scrollIntoView() + .should('be.visible') + .click(); + } } else { - cy.byTestID('name-filter-input').should('be.visible').type(pod); + filterSelector = '[data-test="name-filter-input"]'; } + // Separate the visibility assertion from the type action so Cypress + // re-queries the element for each command independently. + cy.get(filterSelector).scrollIntoView().should('be.visible'); + cy.get(filterSelector).type(pod); }); cy.get(`a[data-test^="${pod}"]`).eq(0).as('podLink').click(); cy.byPFRole('rowgroup') @@ -181,7 +190,6 @@ Cypress.Commands.add('podImage', (pod: string, namespace: string) => { Cypress.Commands.add('assertNamespace', (namespace: string, exists: boolean) => { cy.log('Asserting Namespace: ' + namespace + ' exists: ' + exists); - cy.wait(2000); cy.get('body').then(($body) => { const hasNamespaceBarDropdown = $body.find('[data-test-id="' + LegacyTestIDs.NamespaceBarDropdown + '"]').length > 0; diff --git a/web/cypress/support/monitoring/00.bvt_monitoring.cy.ts b/web/cypress/support/monitoring/00.bvt_monitoring.cy.ts index ce25b7571..c411bd71e 100644 --- a/web/cypress/support/monitoring/00.bvt_monitoring.cy.ts +++ b/web/cypress/support/monitoring/00.bvt_monitoring.cy.ts @@ -34,7 +34,7 @@ export function testBVTMonitoring(perspective: PerspectiveConfig) { listPage.tabShouldHaveText('Silences'); listPage.tabShouldHaveText('Alerting rules'); commonPages.linkShouldExist('Export as CSV'); - commonPages.linkShouldExist('Clear filters'); + commonPages.linkShouldExist('Clear all filters'); listPage.ARRows.shouldBeLoaded(); cy.log('5.2. filter Alerts and click on Alert'); @@ -187,7 +187,7 @@ export function testBVTMonitoring(perspective: PerspectiveConfig) { cy.log('6.8 verify on Alerting Rules list page again'); nav.sidenav.clickNavLink(['Observe', 'Alerting']); nav.tabs.switchTab('Alerting rules'); - listPage.filter.byName(`${WatchdogAlert.ALERTNAME}`); + alertingRuleListPage.filter.byName(`${WatchdogAlert.ALERTNAME}`); alertingRuleListPage.ARShouldBe( `${WatchdogAlert.ALERTNAME}`, `${WatchdogAlert.SEVERITY}`, diff --git a/web/cypress/support/monitoring/03.reg_legacy_dashboards.cy.ts b/web/cypress/support/monitoring/03.reg_legacy_dashboards.cy.ts index 09c86e15d..f25f9a6db 100644 --- a/web/cypress/support/monitoring/03.reg_legacy_dashboards.cy.ts +++ b/web/cypress/support/monitoring/03.reg_legacy_dashboards.cy.ts @@ -112,16 +112,11 @@ export function testLegacyDashboardsRegression(perspective: PerspectiveConfig) { listPage.ARRows.clickAlertingRule(); commonPages.titleShouldHaveText(`${WatchdogAlert.ALERTNAME}`); alertingRuleDetailsPage.clickHideGraphButton(); - cy.wait(2000); cy.byTestID(DataTestIDs.MetricGraph).should('not.exist'); alertingRuleDetailsPage.clickShowGraphButton(); - cy.wait(2000); cy.byTestID(DataTestIDs.MetricGraph).should('be.visible'); - cy.wait(2000); alertingRuleDetailsPage.clickHideGraphButton(); - cy.wait(2000); cy.byTestID(DataTestIDs.MetricGraph).should('not.exist'); - cy.wait(2000); cy.log('4.4 Observe > Alert details - Verify graph is visible'); cy.byTestID(DataTestIDs.AlertResourceLink).first().click(); diff --git a/web/cypress/support/monitoring/06.reg_legacy_dashboards_namespace.cy.ts b/web/cypress/support/monitoring/06.reg_legacy_dashboards_namespace.cy.ts index 4fe3cd5bc..4f576ba49 100644 --- a/web/cypress/support/monitoring/06.reg_legacy_dashboards_namespace.cy.ts +++ b/web/cypress/support/monitoring/06.reg_legacy_dashboards_namespace.cy.ts @@ -15,7 +15,6 @@ import { alertingRuleDetailsPage } from '../../views/alerting-rule-details-page' import { alerts } from '../../fixtures/monitoring/alert'; import { listPage } from '../../views/list-page'; import { commonPages } from '../../views/common'; -import { guidedTour } from '../../views/tour'; export interface PerspectiveConfig { name: string; @@ -76,9 +75,6 @@ export function testLegacyDashboardsRegressionNamespace(perspective: Perspective it(`${perspective.name} perspective - Dashboards (legacy) - No kebab dropdown`, () => { cy.log('3.1 Single Stat - No kebab dropdown'); - cy.visit('/'); - guidedTour.close(); - cy.validateLogin(); nav.sidenav.clickNavLink(['Observe', 'Dashboards']); commonPages.titleShouldHaveText('Dashboards'); cy.changeNamespace('openshift-monitoring'); diff --git a/web/cypress/support/perses/01.coo_list_perses_admin.cy.ts b/web/cypress/support/perses/01.coo_list_perses_admin.cy.ts index 7eed77d2d..4244bf4e1 100644 --- a/web/cypress/support/perses/01.coo_list_perses_admin.cy.ts +++ b/web/cypress/support/perses/01.coo_list_perses_admin.cy.ts @@ -367,7 +367,7 @@ export function testCOOListPersesDuplicateDashboard(perspective: PerspectiveConf cy.log(`6.4. Back to the list and duplicate to another project`); persesDashboardsPage.backToListPersesDashboardsPage(); - + cy.wait(2000); listPersesDashboardsPage.filter.byProject('perses-dev'); listPersesDashboardsPage.filter.byName( persesDashboardsDashboardDropdownPersesDev.PERSES_DASHBOARD_SAMPLE[0], diff --git a/web/cypress/support/perses/03.coo_create_perses_admin.cy.ts b/web/cypress/support/perses/03.coo_create_perses_admin.cy.ts index dab4172e8..877eb76be 100644 --- a/web/cypress/support/perses/03.coo_create_perses_admin.cy.ts +++ b/web/cypress/support/perses/03.coo_create_perses_admin.cy.ts @@ -96,7 +96,7 @@ export function testCOOCreatePerses(perspective: PerspectiveConfig) { persesCreateDashboardsPage.selectProject('openshift-cluster-observability-operator'); persesCreateDashboardsPage.enterDashboardName(dashboardName); persesCreateDashboardsPage.createDashboardDialogCreateButton(); - persesCreateDashboardsPage.assertDuplicatedNameValidation(); + persesCreateDashboardsPage.assertDuplicatedNameValidationFed(dashboardName); cy.log(`2.7. Create another dashboard with the same name in other project`); persesCreateDashboardsPage.selectProject('perses-dev'); diff --git a/web/cypress/support/perses/04.coo_import_perses_admin.cy.ts b/web/cypress/support/perses/04.coo_import_perses_admin.cy.ts index aee80d33d..f95af5101 100644 --- a/web/cypress/support/perses/04.coo_import_perses_admin.cy.ts +++ b/web/cypress/support/perses/04.coo_import_perses_admin.cy.ts @@ -53,7 +53,6 @@ export function testCOOImportPerses(perspective: PerspectiveConfig) { cy.log(`1.10 Assert failed to migrate Grafana dashboard`); persesImportDashboardsPage.assertFailedToMigrateGrafanaDashboard(); - persesDashboardsPage.closeAlert(); cy.log(`1.11 Cancel import`); persesImportDashboardsPage.clickCancelButton(); @@ -106,7 +105,6 @@ export function testCOOImportPerses(perspective: PerspectiveConfig) { persesImportDashboardsPage.clickImportFileButton(); persesImportDashboardsPage.assertDuplicatedDashboardError(); persesImportDashboardsPage.clickCancelButton(); - persesDashboardsPage.closeAlert(); }); it(`3. ${perspective.name} perspective - Import Dashboard - Perses dashboard - JSON file`, () => { diff --git a/web/cypress/support/perses/99.coo_rbac_perses_user1.cy.ts b/web/cypress/support/perses/99.coo_rbac_perses_user1.cy.ts index a6f51a097..0325bcf86 100644 --- a/web/cypress/support/perses/99.coo_rbac_perses_user1.cy.ts +++ b/web/cypress/support/perses/99.coo_rbac_perses_user1.cy.ts @@ -442,9 +442,11 @@ export function testCOORBACPersesTestsDevUser1(perspective: PerspectiveConfig) { cy.log(`6.4. Change namespace to openshift-cluster-observability-operator`); cy.changeNamespace('openshift-cluster-observability-operator'); + cy.wait(2000); cy.log(`6.5. Assert Kebab icon is enabled`); listPersesDashboardsPage.clearAllFilters(); + listPersesDashboardsPage.filter.byProject('openshift-cluster-observability-operator'); listPersesDashboardsPage.filter.byName( persesDashboardsDashboardDropdownCOO.K8S_COMPUTE_RESOURCES_CLUSTER[0], ); @@ -452,11 +454,11 @@ export function testCOORBACPersesTestsDevUser1(perspective: PerspectiveConfig) { listPersesDashboardsPage.assertKebabIconOptions(); listPersesDashboardsPage.clickKebabIcon(); - cy.log(`6.2. Change namespace to All Projects`); + cy.log(`6.6. Change namespace to All Projects`); cy.changeNamespace('All Projects'); listPersesDashboardsPage.clearAllFilters(); - cy.log(`6.3. Filter by Project and Name`); + cy.log(`6.7. Filter by Project and Name`); listPersesDashboardsPage.filter.byProject('observ-test'); listPersesDashboardsPage.filter.byName( persesDashboardsDashboardDropdownPersesDev.PERSES_DASHBOARD_SAMPLE[0], @@ -466,7 +468,7 @@ export function testCOORBACPersesTestsDevUser1(perspective: PerspectiveConfig) { listPersesDashboardsPage.assertKebabIconDisabled(); listPersesDashboardsPage.clearAllFilters(); - cy.log(`6.4. Filter by Project and Name`); + cy.log(`6.8. Filter by Project and Name`); listPersesDashboardsPage.filter.byProject('openshift-cluster-observability-operator'); listPersesDashboardsPage.filter.byName( persesDashboardsDashboardDropdownCOO.K8S_COMPUTE_RESOURCES_CLUSTER[0], diff --git a/web/cypress/views/alerting-rule-list-page.ts b/web/cypress/views/alerting-rule-list-page.ts index f82edd53c..1f640e65a 100644 --- a/web/cypress/views/alerting-rule-list-page.ts +++ b/web/cypress/views/alerting-rule-list-page.ts @@ -1,4 +1,4 @@ -import { DataTestIDs, Classes } from '../../src/components/data-test'; +import { DataTestIDs, Classes, FilterOUIAIDs } from '../../src/components/data-test'; import { Source } from '../fixtures/monitoring/constants'; import { listPage } from './list-page'; @@ -27,6 +27,25 @@ export const alertingRuleListPage = { throw error; } }, + + byName: (name: string, ouiaId: string = FilterOUIAIDs.RuleNameFilter) => { + cy.log('listPage.filter.byName'); + try { + listPage.filter.selectAttribute('Name'); + cy.byOUIAID(`${ouiaId}-input`) + .find('input') + .scrollIntoView() + .as('input') + .should('be.visible'); + cy.get('@input', { timeout: 10000 }) + .scrollIntoView() + .type(name + '{enter}'); + cy.get('@input', { timeout: 10000 }).scrollIntoView().should('have.attr', 'value', name); + } catch (error) { + cy.log(`${error.message}`); + throw error; + } + }, }, clickAlertingRule: (alertRule: string) => { diff --git a/web/cypress/views/common.ts b/web/cypress/views/common.ts index 21f378c25..22b844456 100644 --- a/web/cypress/views/common.ts +++ b/web/cypress/views/common.ts @@ -7,7 +7,9 @@ export const commonPages = { projectDropdownShouldExist: () => cy.byLegacyTestID('namespace-bar-dropdown').should('exist'), titleShouldHaveText: (title: string) => { cy.log('commonPages.titleShouldHaveText - ' + `${title}`); - cy.waitUntil(() => cy.bySemanticElement('h1', title).should('be.visible'), { timeout: 60000 }); + cy.waitUntil(() => cy.bySemanticElement('h1', title).scrollIntoView().should('be.visible'), { + timeout: 60000, + }); }, titleModalShouldHaveText: (title: string) => { diff --git a/web/cypress/views/metrics.ts b/web/cypress/views/metrics.ts index 8a6a304ed..137ae87f3 100644 --- a/web/cypress/views/metrics.ts +++ b/web/cypress/views/metrics.ts @@ -141,7 +141,7 @@ export const metricsPage = { unitsDropdownAssertion: () => { cy.log('metricsPage.unitsDropdownAssertion'); - cy.byTestID(DataTestIDs.MetricGraphUnitsDropDown).should('be.visible').click(); + cy.byTestID(DataTestIDs.MetricGraphUnitsDropDown).scrollIntoView().should('be.visible').click(); const units = Object.values(MetricsPageUnits); units.forEach((unit) => { diff --git a/web/cypress/views/perses-dashboards-create-dashboard.ts b/web/cypress/views/perses-dashboards-create-dashboard.ts index cbcaa8b2f..670dc8725 100644 --- a/web/cypress/views/perses-dashboards-create-dashboard.ts +++ b/web/cypress/views/perses-dashboards-create-dashboard.ts @@ -1,5 +1,9 @@ import { Classes, IDs, persesAriaLabels } from '../../src/components/data-test'; -import { persesCreateDashboard, persesDashboardsModalTitles } from '../fixtures/perses/constants'; +import { + persesCreateDashboard, + persesDashboardsDuplicateDashboard, + persesDashboardsModalTitles, +} from '../fixtures/perses/constants'; export const persesCreateDashboardsPage = { createDashboardShouldBeLoaded: () => { @@ -65,15 +69,29 @@ export const persesCreateDashboardsPage = { assertMaxLengthValidation: () => { cy.log('persesCreateDashboardsPage.assertMaxLengthValidation'); cy.byPFRole('dialog') - .find(Classes.PersesCreateDashboardDashboardNameError) - .should('have.text', `${persesCreateDashboard.DIALOG_MAX_LENGTH_VALIDATION}`) + .find('h4') + .should('have.text', persesCreateDashboard.DIALOG_MAX_LENGTH_VALIDATION) .should('be.visible'); }, assertDuplicatedNameValidation: () => { cy.log('persesCreateDashboardsPage.assertDuplicatedNameValidation'); - cy.get(Classes.PersesDuplicateDashboardNameError) - .should('have.text', persesCreateDashboard.DIALOG_DUPLICATED_NAME_BKD_VALIDATION) + cy.byPFRole('dialog') + .find('h4') + .should('have.text', persesCreateDashboard.DIALOG_CREATE_NAME_BKD_VALIDATION) + .should('be.visible'); + }, + + assertDuplicatedNameValidationFed: (dashboardName: string) => { + cy.log('persesCreateDashboardsPage.assertDuplicatedNameValidationFed'); + cy.byPFRole('dialog') + .find(Classes.PersesCreateDashboardDashboardNameError) + .should( + 'have.text', + persesDashboardsDuplicateDashboard.DIALOG_DUPLICATED_NAME_FED_VALIDATION_1 + + dashboardName + + persesDashboardsDuplicateDashboard.DIALOG_DUPLICATED_NAME_FED_VALIDATION_2, + ) .should('be.visible'); }, diff --git a/web/cypress/views/perses-dashboards-edit-variables.ts b/web/cypress/views/perses-dashboards-edit-variables.ts index 7bb9f6a63..4cb7d3c4e 100644 --- a/web/cypress/views/perses-dashboards-edit-variables.ts +++ b/web/cypress/views/perses-dashboards-edit-variables.ts @@ -129,6 +129,7 @@ export const persesDashboardsEditVariables = { if (allowAllValue) { cy.get('input[name="' + editPersesDashboardsAddVariable.inputAllowAllValue + '"]').click(); if (customAllValue !== undefined && customAllValue !== '') { + cy.get('input[type="checkbox"]').eq(2).click(); cy.get('input[name="' + editPersesDashboardsAddVariable.inputCustomAllValue + '"]') .clear() .type(customAllValue); diff --git a/web/cypress/views/perses-dashboards-list-dashboards.ts b/web/cypress/views/perses-dashboards-list-dashboards.ts index 139ac8c8e..58d6934ec 100644 --- a/web/cypress/views/perses-dashboards-list-dashboards.ts +++ b/web/cypress/views/perses-dashboards-list-dashboards.ts @@ -302,8 +302,8 @@ export const listPersesDashboardsPage = { assertDuplicateDashboardAlreadyExists: () => { cy.log('listPersesDashboardsPage.assertDuplicateDashboardAlreadyExists'); - cy.byPFRole('dialog') - .find(Classes.PersesCreateDashboardDashboardNameError) + cy.byPFRole('list') + .find('h4') .contains(persesDashboardsDuplicateDashboard.DIALOG_DUPLICATED_NAME_VALIDATION) .should('be.visible'); }, diff --git a/web/cypress/views/perses-dashboards-panel.ts b/web/cypress/views/perses-dashboards-panel.ts index a6f2e0c53..298f08adf 100644 --- a/web/cypress/views/perses-dashboards-panel.ts +++ b/web/cypress/views/perses-dashboards-panel.ts @@ -27,16 +27,12 @@ export const persesDashboardsPanel = { .contains('Type') .should('be.visible'); cy.get('#' + IDs.persesDashboardAddPanelForm) - .parent('div') - .find('h2') .siblings('div') .find('button') .contains('Add') .should('be.visible') .and('have.attr', 'disabled'); cy.get('#' + IDs.persesDashboardAddPanelForm) - .parent('div') - .find('h2') .siblings('div') .find('button') .contains('Cancel') @@ -185,8 +181,6 @@ export const persesDashboardsPanel = { break; } cy.get('#' + IDs.persesDashboardAddPanelForm) - .parent('div') - .find('h2') .siblings('div') .find('button') .contains('Add') @@ -272,16 +266,12 @@ export const persesDashboardsPanel = { .contains('Type') .should('be.visible'); cy.get('#' + IDs.persesDashboardAddPanelForm) - .parent('div') - .find('h2') .siblings('div') .find('button') .contains('Apply') .should('be.visible') .and('have.attr', 'disabled'); cy.get('#' + IDs.persesDashboardAddPanelForm) - .parent('div') - .find('h2') .siblings('div') .find('button') .contains('Cancel') @@ -301,8 +291,6 @@ export const persesDashboardsPanel = { persesDashboardsPanel.clickDropdownAndSelectOption('Group', group); persesDashboardsPanel.clickDropdownAndSelectOption('Type', type); cy.get('#' + IDs.persesDashboardAddPanelForm) - .parent('div') - .find('h2') .siblings('div') .find('button') .contains('Apply') diff --git a/web/cypress/views/perses-dashboards.ts b/web/cypress/views/perses-dashboards.ts index 8d5382503..b188a0972 100644 --- a/web/cypress/views/perses-dashboards.ts +++ b/web/cypress/views/perses-dashboards.ts @@ -170,6 +170,7 @@ export const persesDashboardsPage = { cy.byTestID(DataTestIDs.PersesDashboardDropdown) .find('input') .should('have.value', dashboardName); + cy.wait(2000); }, clickTimeRangeDropdown: (timeRange: persesDashboardsTimeRange) => { diff --git a/web/cypress/views/silence-alert-page.ts b/web/cypress/views/silence-alert-page.ts index 0787945e7..23c77f6e2 100644 --- a/web/cypress/views/silence-alert-page.ts +++ b/web/cypress/views/silence-alert-page.ts @@ -388,7 +388,7 @@ export const silenceAlertPage = { cy.log('silenceAlertPage.assertLabelValueError'); cy.get(Classes.SilenceAlertTitle).should( 'contain.text', - 'invalid silence: at least one matcher must not match the empty string', + 'Danger alert:invalid silence: matcher set 0: at least one matcher must not match the empty string', ); }, }; diff --git a/web/src/components/data-test.ts b/web/src/components/data-test.ts index b97bce313..e9d9a51e8 100644 --- a/web/src/components/data-test.ts +++ b/web/src/components/data-test.ts @@ -195,14 +195,14 @@ export const LegacyTestIDs = { export const IDs = { ChartAxis0ChartLabel: 'chart-axis-0-ChartLabel', //id^=IDs.ChartAxis0ChartLabel AxisX ChartAxis1ChartLabel: 'chart-axis-1-ChartLabel', //id^=IDs.ChartAxis1ChartLabel AxisY - persesDashboardCount: 'options-menu-top-pagination', + persesDashboardCount: 'options-menu-bottom-toggle', persesDashboardDownloadButton: 'download-dashboard-button', persesDashboardActionMenuModal: 'action-menu', persesDashboardEditVariablesModalBuiltinButton: 'builtin', persesDashboardAddPanelGroupForm: 'panel-group-editor-form', persesDashboardAddPanelForm: 'panel-editor-form', persesDashboardDiscardChangesDialog: 'discard-dialog', - persesDashboardCreateDashboardName: 'create-modal-dashboard-name-form-group-text-input', + persesDashboardCreateDashboardName: 'text-input-create-dashboard-dialog-name', persesDashboardRenameDashboardName: 'rename-modal-text-input', persesDashboardDuplicateDashboardName: 'duplicate-modal-dashboard-name-form-group-text-input', persesDashboardImportDashboardUploadFileInput: 'import-dashboard-file-filename', From da774994885cd70a89d9ef59603d431add46a29e Mon Sep 17 00:00:00 2001 From: Evelyn Tanigawa Murasaki Date: Tue, 19 May 2026 12:51:05 -0300 Subject: [PATCH 2/3] stability and coderabbit fixes --- web/cypress/e2e/monitoring/00.bvt_admin.cy.ts | 4 -- web/cypress/support/commands/auth-commands.ts | 4 +- .../support/commands/coo-install-commands.ts | 62 +++++++++---------- .../support/commands/dashboards-commands.ts | 36 +++++------ .../support/commands/operator-commands.ts | 2 +- .../commands/traces-logging-commands.ts | 6 +- .../support/commands/utility-commands.ts | 10 +++ .../commands/virtualization-commands.ts | 24 +++---- .../support/monitoring/02.reg_metrics_1.cy.ts | 3 + .../support/monitoring/02.reg_metrics_2.cy.ts | 5 +- .../05.reg_metrics_namespace_2.cy.ts | 3 + web/cypress/views/common.ts | 11 +++- web/cypress/views/metrics.ts | 32 ++++++++-- web/cypress/views/silence-alert-page.ts | 2 +- 14 files changed, 122 insertions(+), 82 deletions(-) diff --git a/web/cypress/e2e/monitoring/00.bvt_admin.cy.ts b/web/cypress/e2e/monitoring/00.bvt_admin.cy.ts index 2ab6d9698..b082cab6b 100644 --- a/web/cypress/e2e/monitoring/00.bvt_admin.cy.ts +++ b/web/cypress/e2e/monitoring/00.bvt_admin.cy.ts @@ -15,8 +15,6 @@ describe('BVT: Monitoring', { tags: ['@smoke', '@monitoring'] }, () => { }); beforeEach(() => { - nav.sidenav.clickNavLink(['Observe', 'Metrics']); - //TODO: remove this double Metrics click after the issue is fixed nav.sidenav.clickNavLink(['Observe', 'Metrics']); commonPages.titleShouldHaveText('Metrics'); cy.changeNamespace('All Projects'); @@ -38,8 +36,6 @@ describe('BVT: Monitoring', { tags: ['@smoke', '@monitoring'] }, () => { nav.sidenav.clickNavLink(['Observe', 'Dashboards']); commonPages.titleShouldHaveText('Dashboards'); nav.sidenav.clickNavLink(['Observe', 'Targets']); - //TODO: remove this double Targets click after the issue is fixed - nav.sidenav.clickNavLink(['Observe', 'Targets']); commonPages.titleShouldHaveText('Metrics targets'); }); // TODO: Intercept Bell GET request to inject an alert (Watchdog to have it opened in diff --git a/web/cypress/support/commands/auth-commands.ts b/web/cypress/support/commands/auth-commands.ts index 1fad0fa9f..2a3a9882b 100644 --- a/web/cypress/support/commands/auth-commands.ts +++ b/web/cypress/support/commands/auth-commands.ts @@ -72,7 +72,7 @@ export const operatorAuthUtils = { } cy.exec( `oc get oauthclient openshift-browser-client -o go-template ` + - `--template="{{index .redirectURIs 0}}" --kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, + `--template="{{index .redirectURIs 0}}" --kubeconfig "${Cypress.env('KUBECONFIG_PATH')}"`, ).then((result) => { if (result.stderr === '') { const oauth = result.stdout; @@ -325,7 +325,7 @@ Cypress.Commands.add('relogin', (provider: string, username: string, password: s // Get the OAuth URL from the cluster (same as performLoginAndAuth does) cy.exec( `oc get oauthclient openshift-browser-client -o go-template ` + - `--template="{{index .redirectURIs 0}}" --kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, + `--template="{{index .redirectURIs 0}}" --kubeconfig "${Cypress.env('KUBECONFIG_PATH')}"`, ).then((result) => { if (result.stderr !== '') { throw new Error(`Failed to get OAuth URL: ${result.stderr}`); diff --git a/web/cypress/support/commands/coo-install-commands.ts b/web/cypress/support/commands/coo-install-commands.ts index 578c9f81e..3cb475c66 100644 --- a/web/cypress/support/commands/coo-install-commands.ts +++ b/web/cypress/support/commands/coo-install-commands.ts @@ -21,9 +21,9 @@ export const cooInstallUtils = { cy.exec( `oc label namespace ${ MCP.namespace - } openshift.io/cluster-monitoring=true --overwrite=true --kubeconfig ${Cypress.env( + } openshift.io/cluster-monitoring=true --overwrite=true --kubeconfig "${Cypress.env( 'KUBECONFIG_PATH', - )}`, + )}"`, ); } else if (Cypress.env('KONFLUX_COO_BUNDLE_IMAGE')) { cy.log( @@ -31,28 +31,28 @@ export const cooInstallUtils = { ); cy.log('Install Cluster Observability Operator'); cy.exec( - `oc --kubeconfig ${Cypress.env( + `oc --kubeconfig "${Cypress.env( 'KUBECONFIG_PATH', - )} apply -f ./cypress/fixtures/coo/coo-imagecontentsourcepolicy.yaml`, + )}" apply -f ./cypress/fixtures/coo/coo-imagecontentsourcepolicy.yaml`, ); cy.exec( - `oc create namespace ${MCP.namespace} --kubeconfig ${Cypress.env( + `oc create namespace ${MCP.namespace} --kubeconfig "${Cypress.env( 'KUBECONFIG_PATH', - )} --dry-run=client -o yaml | oc apply --kubeconfig ${Cypress.env('KUBECONFIG_PATH')} -f -`, + )}" --dry-run=client -o yaml | oc apply --kubeconfig "${Cypress.env('KUBECONFIG_PATH')}" -f -`, ); cy.exec( `oc label namespace ${ MCP.namespace - } openshift.io/cluster-monitoring=true --overwrite=true --kubeconfig ${Cypress.env( + } openshift.io/cluster-monitoring=true --overwrite=true --kubeconfig "${Cypress.env( 'KUBECONFIG_PATH', - )}`, + )}"`, ); cy.exec( `operator-sdk run bundle --timeout=10m --namespace ${ MCP.namespace } --security-context-config restricted ${Cypress.env( 'KONFLUX_COO_BUNDLE_IMAGE', - )} --kubeconfig ${Cypress.env('KUBECONFIG_PATH')} --verbose `, + )} --kubeconfig "${Cypress.env('KUBECONFIG_PATH')}" --verbose `, { timeout: installTimeoutMilliseconds }, ); } else if (Cypress.env('CUSTOM_COO_BUNDLE_IMAGE')) { @@ -61,42 +61,42 @@ export const cooInstallUtils = { ); cy.log('Install Cluster Observability Operator'); cy.exec( - `oc --kubeconfig ${Cypress.env( + `oc --kubeconfig "${Cypress.env( 'KUBECONFIG_PATH', - )} apply -f ./cypress/fixtures/coo/coo-imagecontentsourcepolicy.yaml`, + )}" apply -f ./cypress/fixtures/coo/coo-imagecontentsourcepolicy.yaml`, ); cy.exec( - `oc create namespace ${MCP.namespace} --kubeconfig ${Cypress.env( + `oc create namespace ${MCP.namespace} --kubeconfig "${Cypress.env( 'KUBECONFIG_PATH', - )} --dry-run=client -o yaml | oc apply --kubeconfig ${Cypress.env('KUBECONFIG_PATH')} -f -`, + )}" --dry-run=client -o yaml | oc apply --kubeconfig "${Cypress.env('KUBECONFIG_PATH')}" -f -`, ); cy.exec( `oc label namespace ${ MCP.namespace - } openshift.io/cluster-monitoring=true --overwrite=true --kubeconfig ${Cypress.env( + } openshift.io/cluster-monitoring=true --overwrite=true --kubeconfig "${Cypress.env( 'KUBECONFIG_PATH', - )}`, + )}"`, ); cy.exec( `operator-sdk run bundle --timeout=10m --namespace ${ MCP.namespace } --security-context-config restricted ${Cypress.env( 'CUSTOM_COO_BUNDLE_IMAGE', - )} --kubeconfig ${Cypress.env('KUBECONFIG_PATH')} --verbose `, + )} --kubeconfig "${Cypress.env('KUBECONFIG_PATH')}" --verbose `, { timeout: installTimeoutMilliseconds }, ); } else if (Cypress.env('FBC_STAGE_COO_IMAGE')) { cy.log('FBC_COO_IMAGE is set. COO operator will be installed from FBC image.'); cy.log('Install Cluster Observability Operator'); cy.exec( - `oc --kubeconfig ${Cypress.env( + `oc --kubeconfig "${Cypress.env( 'KUBECONFIG_PATH', - )} apply -f ./cypress/fixtures/coo/coo-imagecontentsourcepolicy.yaml`, + )}" apply -f ./cypress/fixtures/coo/coo-imagecontentsourcepolicy.yaml`, ); cy.exec('./cypress/fixtures/coo/coo_stage.sh', { env: { FBC_STAGE_COO_IMAGE: Cypress.env('FBC_STAGE_COO_IMAGE'), - KUBECONFIG: Cypress.env('KUBECONFIG_PATH'), + KUBECONFIG: Cypress.env('KUBECONFIG_PATH') as string, }, timeout: installTimeoutMilliseconds, }); @@ -109,7 +109,7 @@ export const cooInstallUtils = { waitForCOOReady(MCP: { namespace: string }): void { cy.log('Check Cluster Observability Operator status'); - const kubeconfig = Cypress.env('KUBECONFIG_PATH'); + const kubeconfig = Cypress.env('KUBECONFIG_PATH') as string; cy.exec(`oc project ${MCP.namespace} --kubeconfig ${kubeconfig}`); @@ -169,7 +169,7 @@ export const cooInstallUtils = { cy.log('Remove Cluster Observability Operator namespace'); - cy.exec(`oc get namespace ${MCP.namespace} --kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, { + cy.exec(`oc get namespace ${MCP.namespace} --kubeconfig "${Cypress.env('KUBECONFIG_PATH')}"`, { timeout: readyTimeoutMilliseconds, failOnNonZeroExit: false, }).then((checkResult) => { @@ -179,7 +179,7 @@ export const cooInstallUtils = { cy.exec( `oc delete csv --all -n ${ MCP.namespace - } --ignore-not-found --wait=false --kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, + } --ignore-not-found --wait=false --kubeconfig "${Cypress.env('KUBECONFIG_PATH')}"`, { timeout: 30000, failOnNonZeroExit: false }, ).then((result) => { if (result.code === 0) { @@ -192,7 +192,7 @@ export const cooInstallUtils = { cy.exec( `oc delete subscription --all -n ${ MCP.namespace - } --ignore-not-found --wait=false --kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, + } --ignore-not-found --wait=false --kubeconfig "${Cypress.env('KUBECONFIG_PATH')}"`, { timeout: 30000, failOnNonZeroExit: false }, ).then((result) => { if (result.code === 0) { @@ -205,7 +205,7 @@ export const cooInstallUtils = { cy.exec( `oc delete namespace ${ MCP.namespace - } --ignore-not-found --wait=false --kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, + } --ignore-not-found --wait=false --kubeconfig "${Cypress.env('KUBECONFIG_PATH')}"`, { timeout: 30000, failOnNonZeroExit: false }, ).then((result) => { if (result.code === 0) { @@ -230,9 +230,9 @@ export const cooInstallUtils = { ); return cy .exec( - `./cypress/fixtures/coo/force_delete_ns.sh ${MCP.namespace} ${Cypress.env( + `./cypress/fixtures/coo/force_delete_ns.sh ${MCP.namespace} "${Cypress.env( 'KUBECONFIG_PATH', - )}`, + )}"`, { failOnNonZeroExit: false, timeout: installTimeoutMilliseconds }, ) .then((result) => { @@ -244,9 +244,9 @@ export const cooInstallUtils = { } cy.exec( - `oc get ns ${MCP.namespace} --kubeconfig ${Cypress.env( + `oc get ns ${MCP.namespace} --kubeconfig "${Cypress.env( 'KUBECONFIG_PATH', - )} -o jsonpath='{.status.phase}'`, + )}" -o jsonpath='{.status.phase}'`, { failOnNonZeroExit: false }, ).then((result) => { if (result.code !== 0) { @@ -262,9 +262,9 @@ export const cooInstallUtils = { }s. Elapsed: ${Math.round(elapsed / 1000)}s`, ); cy.exec( - `./cypress/fixtures/coo/force_delete_ns.sh ${MCP.namespace} ${Cypress.env( + `./cypress/fixtures/coo/force_delete_ns.sh ${MCP.namespace} "${Cypress.env( 'KUBECONFIG_PATH', - )}`, + )}"`, { failOnNonZeroExit: false, timeout: installTimeoutMilliseconds }, ).then((forceResult) => { cy.log(`${elapsed}ms - Force delete output: ${forceResult.stdout}`); @@ -296,7 +296,7 @@ export const cooInstallUtils = { }, waitForPodsDeleted(namespace: string, maxWaitMs: number = 120000): void { - const kubeconfigPath = Cypress.env('KUBECONFIG_PATH'); + const kubeconfigPath = Cypress.env('KUBECONFIG_PATH') as string; const checkIntervalMs = 5000; const startTime = Date.now(); const podPatterns = 'monitoring|perses|perses-0|health-analyzer|troubleshooting-panel|korrel8r'; diff --git a/web/cypress/support/commands/dashboards-commands.ts b/web/cypress/support/commands/dashboards-commands.ts index 407fc86eb..ba2fce080 100644 --- a/web/cypress/support/commands/dashboards-commands.ts +++ b/web/cypress/support/commands/dashboards-commands.ts @@ -26,7 +26,7 @@ export const dashboardsUtils = { setupDashboardsAndPlugins(MCP: { namespace: string }): void { cy.log('Create perses-dev namespace.'); - cy.exec(`oc new-project perses-dev --kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, { + cy.exec(`oc new-project perses-dev --kubeconfig "${Cypress.env('KUBECONFIG_PATH')}"`, { failOnNonZeroExit: false, }); @@ -34,41 +34,41 @@ export const dashboardsUtils = { cy.exec( `oc apply -f ./cypress/fixtures/coo/coo140_perses/dashboards/` + `openshift-cluster-sample-dashboard.yaml ` + - `--kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, + `--kubeconfig "${Cypress.env('KUBECONFIG_PATH')}"`, ); cy.log('Create perses-dashboard-sample instance.'); cy.exec( `oc apply -f ./cypress/fixtures/coo/coo140_perses/dashboards/` + `perses-dashboard-sample.yaml ` + - `--kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, + `--kubeconfig "${Cypress.env('KUBECONFIG_PATH')}"`, ); cy.log('Create prometheus-overview-variables instance.'); cy.exec( `oc apply -f ./cypress/fixtures/coo/coo140_perses/dashboards/` + `prometheus-overview-variables.yaml ` + - `--kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, + `--kubeconfig "${Cypress.env('KUBECONFIG_PATH')}"`, ); cy.log('Create thanos-compact-overview-1var instance.'); cy.exec( `oc apply -f ./cypress/fixtures/coo/coo140_perses/dashboards/` + `thanos-compact-overview-1var.yaml ` + - `--kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, + `--kubeconfig "${Cypress.env('KUBECONFIG_PATH')}"`, ); cy.log('Create Thanos Querier instance.'); cy.exec( `oc apply -f ./cypress/fixtures/coo/coo140_perses/dashboards/` + `thanos-querier-datasource.yaml ` + - `--kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, + `--kubeconfig "${Cypress.env('KUBECONFIG_PATH')}"`, ); cy.exec( `oc label namespace ${MCP.namespace} ` + `openshift.io/cluster-monitoring=true --overwrite=true ` + - `--kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, + `--kubeconfig "${Cypress.env('KUBECONFIG_PATH')}"`, ); waitForPodsReady( @@ -95,7 +95,7 @@ export const dashboardsUtils = { cy.log('Create troubleshooting panel instance.'); cy.exec( `oc apply -f ./cypress/fixtures/coo/troubleshooting-panel-ui-plugin.yaml ` + - `--kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, + `--kubeconfig "${Cypress.env('KUBECONFIG_PATH')}"`, ); cy.log('Troubleshooting panel instance created. Waiting for pods to be ready.'); @@ -167,35 +167,35 @@ export const dashboardsUtils = { cy.executeAndDelete( `oc delete -f ./cypress/fixtures/coo/coo140_perses/dashboards/` + `openshift-cluster-sample-dashboard.yaml ` + - `--ignore-not-found --kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, + `--ignore-not-found --kubeconfig "${Cypress.env('KUBECONFIG_PATH')}"`, ); cy.log('Remove perses-dashboard-sample instance.'); cy.executeAndDelete( `oc delete -f ./cypress/fixtures/coo/coo140_perses/dashboards/` + `perses-dashboard-sample.yaml ` + - `--ignore-not-found --kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, + `--ignore-not-found --kubeconfig "${Cypress.env('KUBECONFIG_PATH')}"`, ); cy.log('Remove prometheus-overview-variables instance.'); cy.executeAndDelete( `oc delete -f ./cypress/fixtures/coo/coo140_perses/dashboards/` + `prometheus-overview-variables.yaml ` + - `--ignore-not-found --kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, + `--ignore-not-found --kubeconfig "${Cypress.env('KUBECONFIG_PATH')}"`, ); cy.log('Remove thanos-compact-overview-1var instance.'); cy.executeAndDelete( `oc delete -f ./cypress/fixtures/coo/coo140_perses/dashboards/` + `thanos-compact-overview-1var.yaml ` + - `--ignore-not-found --kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, + `--ignore-not-found --kubeconfig "${Cypress.env('KUBECONFIG_PATH')}"`, ); cy.log('Remove Thanos Querier instance.'); cy.executeAndDelete( `oc delete -f ./cypress/fixtures/coo/coo140_perses/dashboards/` + `thanos-querier-datasource.yaml ` + - `--ignore-not-found --kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, + `--ignore-not-found --kubeconfig "${Cypress.env('KUBECONFIG_PATH')}"`, ); } else { cy.log('COO_UI_INSTALL is not set. Removing dashboards on COO1.4.0 folder'); @@ -204,35 +204,35 @@ export const dashboardsUtils = { cy.executeAndDelete( `oc delete -f ./cypress/fixtures/coo/coo140_perses/dashboards/` + `openshift-cluster-sample-dashboard.yaml ` + - `--ignore-not-found --kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, + `--ignore-not-found --kubeconfig "${Cypress.env('KUBECONFIG_PATH')}"`, ); cy.log('Remove perses-dashboard-sample instance.'); cy.executeAndDelete( `oc delete -f ./cypress/fixtures/coo/coo140_perses/dashboards/` + `perses-dashboard-sample.yaml ` + - `--ignore-not-found --kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, + `--ignore-not-found --kubeconfig "${Cypress.env('KUBECONFIG_PATH')}"`, ); cy.log('Remove prometheus-overview-variables instance.'); cy.executeAndDelete( `oc delete -f ./cypress/fixtures/coo/coo140_perses/dashboards/` + `prometheus-overview-variables.yaml ` + - `--ignore-not-found --kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, + `--ignore-not-found --kubeconfig "${Cypress.env('KUBECONFIG_PATH')}"`, ); cy.log('Remove thanos-compact-overview-1var instance.'); cy.executeAndDelete( `oc delete -f ./cypress/fixtures/coo/coo140_perses/dashboards/` + `thanos-compact-overview-1var.yaml ` + - `--ignore-not-found --kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, + `--ignore-not-found --kubeconfig "${Cypress.env('KUBECONFIG_PATH')}"`, ); cy.log('Remove Thanos Querier instance.'); cy.executeAndDelete( `oc delete -f ./cypress/fixtures/coo/coo140_perses/dashboards/` + `thanos-querier-datasource.yaml ` + - `--ignore-not-found --kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, + `--ignore-not-found --kubeconfig "${Cypress.env('KUBECONFIG_PATH')}"`, ); } diff --git a/web/cypress/support/commands/operator-commands.ts b/web/cypress/support/commands/operator-commands.ts index 12ae5e72c..68b5b2c89 100644 --- a/web/cypress/support/commands/operator-commands.ts +++ b/web/cypress/support/commands/operator-commands.ts @@ -58,7 +58,7 @@ function removeClusterAdminRole(): void { cy.executeAndDelete( `oc adm policy remove-cluster-role-from-user cluster-admin ${Cypress.env( 'LOGIN_USERNAME', - )} --kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, + )} --kubeconfig "${Cypress.env('KUBECONFIG_PATH')}"`, ); } diff --git a/web/cypress/support/commands/traces-logging-commands.ts b/web/cypress/support/commands/traces-logging-commands.ts index 3d822dfef..13d6f61ab 100644 --- a/web/cypress/support/commands/traces-logging-commands.ts +++ b/web/cypress/support/commands/traces-logging-commands.ts @@ -284,7 +284,7 @@ const tracesUtils = { // eslint-disable-next-line max-len `sleep 15 && oc wait --for=condition=Ready pods --selector=app.kubernetes.io/instance=distributed-tracing -n ${ DTP.namespace - } --timeout=60s --kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, + } --timeout=60s --kubeconfig "${Cypress.env('KUBECONFIG_PATH')}"`, { timeout: 80000, failOnNonZeroExit: true, @@ -661,7 +661,7 @@ const loggingUtils = { // eslint-disable-next-line max-len `sleep 15 && oc wait --for=condition=Ready pods --selector=app.kubernetes.io/instance=logging -n ${ LOGGING_PLUGIN.namespace - } --timeout=60s --kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, + } --timeout=60s --kubeconfig "${Cypress.env('KUBECONFIG_PATH')}"`, { timeout: 80000, failOnNonZeroExit: true, @@ -690,7 +690,7 @@ const loggingUtils = { cy.exec( `oc delete ${LOGGING_PLUGIN.config.kind} ${ LOGGING_PLUGIN.config.name - } --kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, + } --kubeconfig "${Cypress.env('KUBECONFIG_PATH')}"`, { failOnNonZeroExit: false }, ); cy.log('Cleanup Logging UI Plugin completed'); diff --git a/web/cypress/support/commands/utility-commands.ts b/web/cypress/support/commands/utility-commands.ts index 5a1bb7cf8..08b0de298 100644 --- a/web/cypress/support/commands/utility-commands.ts +++ b/web/cypress/support/commands/utility-commands.ts @@ -103,6 +103,16 @@ Cypress.Commands.add('changeNamespace', (namespace: string) => { .contains(namespace) .should('be.visible') .click({ force: true }); + cy.get('body').then(($body) => { + cy.log('Checking namespace: ' + namespace); + const hasNamespaceBarDropdown = + $body.find('[data-test-id="' + LegacyTestIDs.NamespaceBarDropdown + '"]').length > 0; + if (hasNamespaceBarDropdown) { + cy.byLegacyTestID(LegacyTestIDs.NamespaceBarDropdown).should('contain.text', namespace); + } else { + cy.get(Classes.NamespaceDropdown).should('contain.text', namespace); + } + }); cy.log('Namespace changed to: ' + namespace); }); diff --git a/web/cypress/support/commands/virtualization-commands.ts b/web/cypress/support/commands/virtualization-commands.ts index 23211ffc0..886517e8b 100644 --- a/web/cypress/support/commands/virtualization-commands.ts +++ b/web/cypress/support/commands/virtualization-commands.ts @@ -43,12 +43,12 @@ const virtualizationUtils = { cy.log('Install Openshift Virtualization'); cy.exec( - `oc create namespace ${KBV.namespace} --kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, + `oc create namespace ${KBV.namespace} --kubeconfig "${Cypress.env('KUBECONFIG_PATH')}"`, ); cy.exec( `operator-sdk run bundle --timeout=10m --namespace ${KBV.namespace} ${Cypress.env( 'KONFLUX_KBV_BUNDLE_IMAGE', - )} --kubeconfig ${Cypress.env('KUBECONFIG_PATH')} --verbose `, + )} --kubeconfig "${Cypress.env('KUBECONFIG_PATH')}" --verbose `, { timeout: installTimeoutMilliseconds }, ); } else if (Cypress.env('CUSTOM_KBV_BUNDLE_IMAGE')) { @@ -58,12 +58,12 @@ const virtualizationUtils = { cy.log('Install Openshift Virtualization'); cy.exec( - `oc create namespace ${KBV.namespace} --kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, + `oc create namespace ${KBV.namespace} --kubeconfig "${Cypress.env('KUBECONFIG_PATH')}"`, ); cy.exec( `operator-sdk run bundle --timeout=10m --namespace ${KBV.namespace} ${Cypress.env( 'CUSTOM_KBV_BUNDLE_IMAGE', - )} --kubeconfig ${Cypress.env('KUBECONFIG_PATH')} --verbose `, + )} --kubeconfig "${Cypress.env('KUBECONFIG_PATH')}" --verbose `, { timeout: installTimeoutMilliseconds }, ); } else if (Cypress.env('FBC_STAGE_KBV_IMAGE')) { @@ -102,7 +102,7 @@ const virtualizationUtils = { `--for=jsonpath='{.status.phase}'=Succeeded ` + `ClusterServiceVersion/${KBV_OPERATOR_NAME} ` + `-n ${KBV.namespace} ` + - `--timeout=300s --kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, + `--timeout=300s --kubeconfig "${Cypress.env('KUBECONFIG_PATH')}"`, { timeout: readyTimeoutMilliseconds, // Set a long timeout for the 'oc wait' command }, @@ -150,12 +150,12 @@ const virtualizationUtils = { cy.log('Create Hyperconverged instance.'); cy.exec( `oc apply -f ./cypress/fixtures/virtualization/hyperconverged.yaml ` + - `--kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, + `--kubeconfig "${Cypress.env('KUBECONFIG_PATH')}"`, ); cy.exec( `sleep 15 && oc wait --for=condition=Available --selector=app=kubevirt-hyperconverged -n ${ KBV.namespace - } --timeout=60s --kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, + } --timeout=60s --kubeconfig "${Cypress.env('KUBECONFIG_PATH')}"`, { timeout: readyTimeoutMilliseconds, failOnNonZeroExit: true, @@ -206,21 +206,21 @@ const virtualizationUtils = { cy.executeAndDelete( `oc delete HyperConverged kubevirt-hyperconverged -n ${ KBV.namespace - } --ignore-not-found --kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, + } --ignore-not-found --kubeconfig "${Cypress.env('KUBECONFIG_PATH')}"`, ); cy.log('Remove Openshift Virtualization subscription'); cy.executeAndDelete( `oc delete subscription ${config.name} -n ${ KBV.namespace - } --ignore-not-found --kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, + } --ignore-not-found --kubeconfig "${Cypress.env('KUBECONFIG_PATH')}"`, ); cy.log('Remove Openshift Virtualization CSV'); cy.executeAndDelete( `oc delete csv -n ${KBV.namespace} ` + `-l operators.coreos.com/kubevirt-hyperconverged.openshift-cnv ` + - `--ignore-not-found --kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, + `--ignore-not-found --kubeconfig "${Cypress.env('KUBECONFIG_PATH')}"`, ); cy.log('Remove Openshift Virtualization namespace'); @@ -234,14 +234,14 @@ const virtualizationUtils = { cy.executeAndDelete( `oc delete crd --dry-run=client ` + `-l operators.coreos.com/kubevirt-hyperconverged.openshift-cnv ` + - `--ignore-not-found --kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, + `--ignore-not-found --kubeconfig "${Cypress.env('KUBECONFIG_PATH')}"`, ); cy.log('Delete Kubevirt instance.'); cy.executeAndDelete( `oc delete crd ` + `-l operators.coreos.com/kubevirt-hyperconverged.openshift-cnv ` + - `--ignore-not-found --kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`, + `--ignore-not-found --kubeconfig "${Cypress.env('KUBECONFIG_PATH')}"`, ); } }, diff --git a/web/cypress/support/monitoring/02.reg_metrics_1.cy.ts b/web/cypress/support/monitoring/02.reg_metrics_1.cy.ts index 7cbd70870..105335378 100644 --- a/web/cypress/support/monitoring/02.reg_metrics_1.cy.ts +++ b/web/cypress/support/monitoring/02.reg_metrics_1.cy.ts @@ -213,6 +213,9 @@ export function testMetricsRegression1(perspective: PerspectiveConfig) { cy.log('4.11 Stacked Checkbox'); metricsPage.clickStackedCheckboxAndAssert(); + + cy.log('4.12 Delete All Queries'); + metricsPage.clickActionsDeleteAllQueries(); }); //https://issues.redhat.com/browse/OU-974 - [Metrics] - Units - undefined showing in Y axis and tooltip diff --git a/web/cypress/support/monitoring/02.reg_metrics_2.cy.ts b/web/cypress/support/monitoring/02.reg_metrics_2.cy.ts index 6ba5f4b62..9792638b0 100644 --- a/web/cypress/support/monitoring/02.reg_metrics_2.cy.ts +++ b/web/cypress/support/monitoring/02.reg_metrics_2.cy.ts @@ -75,7 +75,7 @@ export function testMetricsRegression2(perspective: PerspectiveConfig) { cy.get(Classes.MetricsPageQueryInput) .eq(1) .should('contain', MetricsPageQueryInput.INSERT_EXAMPLE_QUERY); - cy.byTestID(DataTestIDs.MetricGraph).should('be.visible'); + cy.byTestID(DataTestIDs.MetricGraph).scrollIntoView().should('be.visible'); metricsPage.clickKebabDropdown(0); cy.get(Classes.MenuItemDisabled) .contains(MetricsPageQueryKebabDropdown.HIDE_ALL_SERIES) @@ -316,6 +316,9 @@ export function testMetricsRegression2(perspective: PerspectiveConfig) { .contains(MetricsPageQueryKebabDropdown.HIDE_ALL_SERIES) .should('have.attr', 'aria-disabled', 'true'); cy.byTestID(DataTestIDs.MetricsPageExportCsvDropdownItem).should('not.exist'); + + cy.log('6.18 Delete All Queries'); + metricsPage.clickActionsDeleteAllQueries(); }); it(`${perspective.name} perspective - Metrics > Predefined Queries > Export as CSV`, () => { diff --git a/web/cypress/support/monitoring/05.reg_metrics_namespace_2.cy.ts b/web/cypress/support/monitoring/05.reg_metrics_namespace_2.cy.ts index f5c7e5193..d9e74dcde 100644 --- a/web/cypress/support/monitoring/05.reg_metrics_namespace_2.cy.ts +++ b/web/cypress/support/monitoring/05.reg_metrics_namespace_2.cy.ts @@ -316,6 +316,9 @@ export function testMetricsRegressionNamespace2(perspective: PerspectiveConfig) .contains(MetricsPageQueryKebabDropdown.HIDE_ALL_SERIES) .should('have.attr', 'aria-disabled', 'true'); cy.byTestID(DataTestIDs.MetricsPageExportCsvDropdownItem).should('not.exist'); + + cy.log('6.18 Delete All Queries'); + metricsPage.clickActionsDeleteAllQueries(); }); it(`${perspective.name} perspective - Metrics > Predefined Queries > Export as CSV`, () => { diff --git a/web/cypress/views/common.ts b/web/cypress/views/common.ts index 22b844456..0472673bb 100644 --- a/web/cypress/views/common.ts +++ b/web/cypress/views/common.ts @@ -7,9 +7,14 @@ export const commonPages = { projectDropdownShouldExist: () => cy.byLegacyTestID('namespace-bar-dropdown').should('exist'), titleShouldHaveText: (title: string) => { cy.log('commonPages.titleShouldHaveText - ' + `${title}`); - cy.waitUntil(() => cy.bySemanticElement('h1', title).scrollIntoView().should('be.visible'), { - timeout: 60000, - }); + cy.waitUntil( + () => + Cypress.$('h1') + .toArray() + .some((el) => el.textContent?.trim() === title && Cypress.dom.isVisible(el)), + { timeout: 60000 }, + ); + cy.bySemanticElement('h1', title).scrollIntoView().should('be.visible'); }, titleModalShouldHaveText: (title: string) => { diff --git a/web/cypress/views/metrics.ts b/web/cypress/views/metrics.ts index 137ae87f3..40e0a990a 100644 --- a/web/cypress/views/metrics.ts +++ b/web/cypress/views/metrics.ts @@ -197,6 +197,7 @@ export const metricsPage = { clickActions: () => { cy.log('metricsPage.clickActions'); cy.byTestID(DataTestIDs.MetricsPageActionsDropdownButton) + .scrollIntoView() .should('have.attr', 'aria-expanded', 'false') .click(); }, @@ -292,6 +293,7 @@ export const metricsPage = { * @param expanded * @param index * @param withQuery + * @param withSwitch */ expandCollapseRowAssertion: ( expanded: boolean, @@ -304,10 +306,12 @@ export const metricsPage = { if (withQuery) { cy.get(Classes.MetricsPageQueryInput) .eq(index) + .scrollIntoView() .should('not.contain', MetricsPageQueryInput.EXPRESSION_PRESS_SHIFT_ENTER_FOR_NEWLINES); } else { cy.get(Classes.MetricsPageQueryInput) .eq(index) + .scrollIntoView() .should('contain', MetricsPageQueryInput.EXPRESSION_PRESS_SHIFT_ENTER_FOR_NEWLINES); } @@ -335,7 +339,7 @@ export const metricsPage = { .find('[data-test="' + DataTestIDs.MetricsPageSeriesButton + '"]') .should('have.length.gt', 0); } else { - cy.get(Classes.MetricsPageRows).find('li').eq(index).should('be.visible'); + cy.get(Classes.MetricsPageRows).find('li').eq(index).scrollIntoView().should('be.visible'); cy.get(Classes.MetricsPageRows) .find('li') .eq(index) @@ -371,7 +375,7 @@ export const metricsPage = { .find('[data-test="' + DataTestIDs.MetricsPageDisableEnableQuerySwitch + '"]') .should('have.attr', 'checked'); } - cy.get(Classes.MetricsPageRows).find('li').eq(index).should('be.visible'); + cy.get(Classes.MetricsPageRows).find('li').eq(index).scrollIntoView().should('be.visible'); cy.get(Classes.MetricsPageRows) .find('li') .eq(index) @@ -388,6 +392,7 @@ export const metricsPage = { .find('[data-test="' + DataTestIDs.MetricsPageSeriesButton + '"]') .should('not.exist'); } + cy.log('metricsPage.expandCollapseRowAssertion - Finished'); }, clickActionsDeleteAllQueries: () => { @@ -426,13 +431,19 @@ export const metricsPage = { graphTimespanDropdownAssertion: () => { cy.log('metricsPage.graphTimespanDropdownAssertion'); - cy.byTestID(DataTestIDs.MetricGraphTimespanDropdown).should('be.visible').click(); + cy.byTestID(DataTestIDs.MetricGraphTimespanDropdown) + .scrollIntoView() + .should('be.visible') + .click(); const timespans = Object.values(GraphTimespan); timespans.forEach((timespan) => { cy.log('Graph Timespan: ' + timespan); cy.get(Classes.MenuItem).contains(timespan).should('be.visible'); }); - cy.byTestID(DataTestIDs.MetricGraphTimespanDropdown).should('be.visible').click(); + cy.byTestID(DataTestIDs.MetricGraphTimespanDropdown) + .scrollIntoView() + .should('be.visible') + .click(); }, clickResetZoomButton: () => { @@ -520,7 +531,11 @@ export const metricsPage = { clickKebabDropdown: (index: number) => { cy.log('metricsPage.clickKebabDropdown'); - cy.byTestID(DataTestIDs.KebabDropdownButton).eq(index).click(); + cy.byTestID(DataTestIDs.KebabDropdownButton) + .eq(index) + .scrollIntoView() + .should('be.visible') + .click(); }, kebabDropdownAssertionWithoutQuery: () => { @@ -663,7 +678,10 @@ export const metricsPage = { clickRunQueriesButton: () => { cy.log('metricsPage.clickRunQueriesButton'); - cy.byTestID(DataTestIDs.MetricsPageRunQueriesButton).should('be.visible').click(); + cy.byTestID(DataTestIDs.MetricsPageRunQueriesButton) + .scrollIntoView() + .should('be.visible') + .click(); }, clickDisableEnableQuerySwitch: (index: number) => { @@ -680,10 +698,12 @@ export const metricsPage = { if (enabled) { cy.byTestID(DataTestIDs.MetricsPageDisableEnableQuerySwitch) .eq(index) + .scrollIntoView() .should('have.attr', 'checked'); } else { cy.byTestID(DataTestIDs.MetricsPageDisableEnableQuerySwitch) .eq(index) + .scrollIntoView() .should('not.have.attr', 'checked'); } }, diff --git a/web/cypress/views/silence-alert-page.ts b/web/cypress/views/silence-alert-page.ts index 23c77f6e2..ab0a61c62 100644 --- a/web/cypress/views/silence-alert-page.ts +++ b/web/cypress/views/silence-alert-page.ts @@ -388,7 +388,7 @@ export const silenceAlertPage = { cy.log('silenceAlertPage.assertLabelValueError'); cy.get(Classes.SilenceAlertTitle).should( 'contain.text', - 'Danger alert:invalid silence: matcher set 0: at least one matcher must not match the empty string', + 'at least one matcher must not match the empty string', ); }, }; From 6aa45b888c09de7ba14cb59352cb7121d36f3700 Mon Sep 17 00:00:00 2001 From: Evelyn Tanigawa Murasaki Date: Wed, 20 May 2026 14:02:58 -0300 Subject: [PATCH 3/3] enhancement when long metrics --- web/cypress/views/metrics.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/web/cypress/views/metrics.ts b/web/cypress/views/metrics.ts index 40e0a990a..d21bb1d55 100644 --- a/web/cypress/views/metrics.ts +++ b/web/cypress/views/metrics.ts @@ -713,6 +713,7 @@ export const metricsPage = { if (toEnable) { cy.get(Classes.MetricsPageExpandedRowIcon) .eq(rowIndex) + .scrollIntoView() .find('[data-test="' + DataTestIDs.MetricsPageSeriesButton + '"]') .eq(seriesIndex) .should('have.attr', 'aria-label', 'Show series') @@ -720,6 +721,7 @@ export const metricsPage = { } else { cy.get(Classes.MetricsPageExpandedRowIcon) .eq(rowIndex) + .scrollIntoView() .find('[data-test="' + DataTestIDs.MetricsPageSeriesButton + '"]') .eq(seriesIndex) .should('have.attr', 'aria-label', 'Hide series') @@ -749,11 +751,13 @@ export const metricsPage = { if (unselectAll) { cy.byTestID(DataTestIDs.MetricsPageSelectAllUnselectAllButton) .eq(rowIndex) + .scrollIntoView() .contains('Unselect all') .should('be.visible'); } else { cy.byTestID(DataTestIDs.MetricsPageSelectAllUnselectAllButton) .eq(rowIndex) + .scrollIntoView() .contains('Select all') .should('be.visible'); }