From e8d000748de9f940e9e4a1443c475515bd65d743 Mon Sep 17 00:00:00 2001 From: David Rajnoha Date: Thu, 19 Mar 2026 09:56:59 +0100 Subject: [PATCH 1/2] fix: replace cy.reload() with SPA navigation to fix dynamic plugin chunk loading failures The Incidents component is loaded as a dynamic plugin chunk. cy.reload() causes a full page reload where the Console must re-resolve all plugins from scratch, which silently fails non-deterministically in headless CI, leaving a blank content pane (correct URL and tab, but no component mounted). Replace all cy.reload() usage in the incidents test suite with SPA navigation (goTo: Alerting tab -> Incidents tab), which reliably triggers component unmount/remount via React's routing without requiring plugin re-resolution. Key changes: - goTo() now waits for daysSelectToggle to be visible (assertion-based) - prepareIncidentsPageForSearch uses goTo() instead of cy.reload() - mockIncidents/mockIncidentFixture use goTo() instead of cy.reload() - Consolidate setupIncidentFixture/setupIncidentMock into mockIncidentFixture/ mockIncidents (the setup-only variants were only needed to avoid reload) - switchTab() restored to use .should('be.visible') before click - toggleFilter() improved to avoid re-selecting filter type when already visible - New selectFilterValue/deselectFilterValue helpers for reliable filter toggling Made-with: Cursor --- web/cypress.config.ts | 1 + web/cypress/e2e/incidents/01.incidents.cy.ts | 28 +--- .../regression/01.reg_filtering.cy.ts | 2 - .../02.reg_ui_charts_comprehensive.cy.ts | 1 - .../03-04.reg_e2e_firing_alerts.cy.ts | 9 +- .../regression/03.reg_api_calls.cy.ts | 2 - .../regression/04.reg_redux_effects.cy.ts | 13 +- .../prometheus-mocks.ts | 17 ++- web/cypress/views/incidents-page.ts | 127 +++++++++++++++--- web/cypress/views/nav.ts | 2 +- 10 files changed, 141 insertions(+), 61 deletions(-) diff --git a/web/cypress.config.ts b/web/cypress.config.ts index 99f391490..add189f0c 100644 --- a/web/cypress.config.ts +++ b/web/cypress.config.ts @@ -52,6 +52,7 @@ export default defineConfig({ typeDelay: 200, }, fixturesFolder: 'cypress/fixtures', + pageLoadTimeout: 60000, defaultCommandTimeout: 80000, //due to performance loading issue on console readyTimeoutMilliseconds: 120000, installTimeoutMilliseconds: 600000, diff --git a/web/cypress/e2e/incidents/01.incidents.cy.ts b/web/cypress/e2e/incidents/01.incidents.cy.ts index b1819ec35..29fdd6109 100644 --- a/web/cypress/e2e/incidents/01.incidents.cy.ts +++ b/web/cypress/e2e/incidents/01.incidents.cy.ts @@ -2,13 +2,11 @@ The test verifies the basic functionality of the Incidents page and serves as a verification that the Incidents View is working as expected. -Currently, it depends on an alert being present in the cluster. -In the future, mocking requests / injecting alerts should be considered. -Natural creation of the alert is done in the 00.coo_incidents_e2e.cy.ts test, -but takes significant time. +All tests use mocked data. Tests 1-3 use a default fixture (incident content +is irrelevant for toolbar/filter verification). Tests 4-5 switch mocks +mid-test for empty state and traversal scenarios. */ -import { commonPages } from '../../views/common'; import { incidentsPage } from '../../views/incidents-page'; const MCP = { @@ -26,24 +24,13 @@ const MP = { operatorName: 'Cluster Monitoring Operator', }; -const ALERTNAME = 'Watchdog'; -const NAMESPACE = 'openshift-monitoring'; -const SEVERITY = 'Critical'; -const ALERT_DESC = 'This is an alert meant to ensure that the entire alerting pipeline is functional. This alert is always firing, therefore it should always be firing in Alertmanager and always fire against a receiver. There are integrations with various notification mechanisms that send a notification when this alert is not firing. For example the "DeadMansSnitch" integration in PagerDuty.' -const ALERT_SUMMARY = 'An alert that should always be firing to certify that Alertmanager is working properly.' describe('BVT: Incidents - UI', { tags: ['@smoke', '@incidents'] }, () => { before(() => { cy.beforeBlockCOO(MCP, MP, { dashboards: false, troubleshootingPanel: false }); + cy.mockIncidentFixture('incident-scenarios/1-single-incident-firing-critical-and-warning-alerts.yaml'); }); - beforeEach(() => { - cy.log('Navigate to Observe → Incidents'); - incidentsPage.goTo(); - // Temporary workaround for testing against locally built instances. - cy.transformMetrics(); - }); - it('1. Admin perspective - Incidents page - Toolbar and charts toggle functionality', () => { cy.log('1.1 Verify toolbar and toggle charts button'); incidentsPage.elements.toolbar().should('be.visible'); @@ -80,14 +67,14 @@ describe('BVT: Incidents - UI', { tags: ['@smoke', '@incidents'] }, () => { cy.log('4.1 Verify chart titles are visible'); incidentsPage.elements.incidentsChartTitle().should('be.visible'); incidentsPage.elements.alertsChartTitle().should('be.visible'); - cy.log('4.2 Verify alerts chart shows empty state'); incidentsPage.elements.alertsChartEmptyState().should('exist'); }); it('5. Admin perspective - Incidents page - Traverse Incident Table', () => { + incidentsPage.goTo(); + cy.log('5.1 Traverse incident table'); - incidentsPage.clearAllFilters(); cy.mockIncidents([]); incidentsPage.findIncidentWithAlert('TargetAlert').should('be.false'); @@ -95,9 +82,8 @@ describe('BVT: Incidents - UI', { tags: ['@smoke', '@incidents'] }, () => { cy.mockIncidentFixture('incident-scenarios/1-single-incident-firing-critical-and-warning-alerts.yaml'); incidentsPage.findIncidentWithAlert('TargetAlert').should('be.false'); - incidentsPage.clearAllFilters cy.log('5.3 Verify traversing incident table works when the alert is present'); cy.mockIncidentFixture('incident-scenarios/6-multi-incident-target-alert-scenario.yaml'); - incidentsPage.findIncidentWithAlert('TargetAlert').should('be.true'); + incidentsPage.findIncidentWithAlert('TargetAlert').should('be.true'); }); }); \ No newline at end of file diff --git a/web/cypress/e2e/incidents/regression/01.reg_filtering.cy.ts b/web/cypress/e2e/incidents/regression/01.reg_filtering.cy.ts index 200b4e9fc..c69542ed7 100644 --- a/web/cypress/e2e/incidents/regression/01.reg_filtering.cy.ts +++ b/web/cypress/e2e/incidents/regression/01.reg_filtering.cy.ts @@ -32,8 +32,6 @@ describe('Regression: Incidents Filtering', { tags: ['@incidents'] }, () => { }); beforeEach(() => { - cy.log('Navigate to Observe → Incidents'); - incidentsPage.goTo(); cy.log('Setting up comprehensive filtering test scenarios'); cy.mockIncidentFixture('incident-scenarios/7-comprehensive-filtering-test-scenarios.yaml'); }); diff --git a/web/cypress/e2e/incidents/regression/02.reg_ui_charts_comprehensive.cy.ts b/web/cypress/e2e/incidents/regression/02.reg_ui_charts_comprehensive.cy.ts index 34dc9f386..447b3838b 100644 --- a/web/cypress/e2e/incidents/regression/02.reg_ui_charts_comprehensive.cy.ts +++ b/web/cypress/e2e/incidents/regression/02.reg_ui_charts_comprehensive.cy.ts @@ -92,7 +92,6 @@ describe('Regression: Charts UI - Comprehensive', { tags: ['@incidents'] }, () = }); beforeEach(() => { - incidentsPage.goTo(); cy.mockIncidentFixture('incident-scenarios/12-charts-ui-comprehensive.yaml'); }); diff --git a/web/cypress/e2e/incidents/regression/03-04.reg_e2e_firing_alerts.cy.ts b/web/cypress/e2e/incidents/regression/03-04.reg_e2e_firing_alerts.cy.ts index 55af0c584..a6537df66 100644 --- a/web/cypress/e2e/incidents/regression/03-04.reg_e2e_firing_alerts.cy.ts +++ b/web/cypress/e2e/incidents/regression/03-04.reg_e2e_firing_alerts.cy.ts @@ -36,11 +36,13 @@ const MP = { describe('Regression: Time-Based Alert Resolution (E2E with Firing Alerts)', { tags: ['@incidents', '@slow', '@e2e-real'] }, () => { let currentAlertName: string; + before(() => { cy.beforeBlockCOO(MCP, MP, { dashboards: false, troubleshootingPanel: false }); - cy.log('Create or reuse firing alert for testing'); - cy.createKubePodCrashLoopingAlert('TimeBasedResolution2').then((alertName) => { + cy.log('Create firing alert for testing'); + cy.cleanupIncidentPrometheusRules(); + cy.createKubePodCrashLoopingAlert().then((alertName) => { currentAlertName = alertName; cy.log(`Test will monitor alert: ${currentAlertName}`); }); @@ -50,6 +52,7 @@ describe('Regression: Time-Based Alert Resolution (E2E with Firing Alerts)', { t it('1. Section 3.3 - Alert not incorrectly marked as resolved after time passes', () => { cy.log('1.1 Navigate to Incidents page and clear filters'); incidentsPage.goTo(); + cy.wait(10000); incidentsPage.clearAllFilters(); const intervalMs = 60_000; @@ -161,6 +164,7 @@ describe('Regression: Time-Based Alert Resolution (E2E with Firing Alerts)', { t it('2. Section 4.7 - Prometheus query end time updates to current time on filter refresh', () => { cy.log('2.1 Navigate to Incidents page and clear filters'); incidentsPage.goTo(); + cy.wait(10000); incidentsPage.clearAllFilters(); cy.log('2.2 Capture initial page load time'); @@ -262,6 +266,7 @@ describe('Regression: Time-Based Alert Resolution (E2E with Firing Alerts)', { t it('3. Verify alert lifecycle - alert continues firing throughout test', () => { cy.log('3.1 Navigate to Incidents page'); incidentsPage.goTo(); + cy.wait(10000); incidentsPage.clearAllFilters(); cy.log('3.2 Search for and select incident with custom alert'); diff --git a/web/cypress/e2e/incidents/regression/03.reg_api_calls.cy.ts b/web/cypress/e2e/incidents/regression/03.reg_api_calls.cy.ts index cb91c1e3f..3d29c5f32 100644 --- a/web/cypress/e2e/incidents/regression/03.reg_api_calls.cy.ts +++ b/web/cypress/e2e/incidents/regression/03.reg_api_calls.cy.ts @@ -33,8 +33,6 @@ describe('Regression: Silences Not Applied Correctly', { tags: ['@incidents'] }, }); beforeEach(() => { - cy.log('Navigate to Observe → Incidents'); - incidentsPage.goTo(); cy.log('Setting up silenced alerts mixed scenario'); cy.mockIncidentFixture('incident-scenarios/9-silenced-alerts-mixed-scenario.yaml'); }); diff --git a/web/cypress/e2e/incidents/regression/04.reg_redux_effects.cy.ts b/web/cypress/e2e/incidents/regression/04.reg_redux_effects.cy.ts index dec7b90b1..aa06dd737 100644 --- a/web/cypress/e2e/incidents/regression/04.reg_redux_effects.cy.ts +++ b/web/cypress/e2e/incidents/regression/04.reg_redux_effects.cy.ts @@ -37,8 +37,6 @@ describe('Regression: Redux State Management', { tags: ['@incidents', '@incident }); beforeEach(() => { - cy.log('Navigate to Observe → Incidents'); - incidentsPage.goTo(); cy.log('Setting up comprehensive filtering test scenarios'); cy.mockIncidentFixture('incident-scenarios/7-comprehensive-filtering-test-scenarios.yaml'); }); @@ -144,10 +142,8 @@ describe('Regression: Redux State Management', { tags: ['@incidents', '@incident it('3. Adding filter when incident selected should not remove the incident ID filter', () => { cy.log('3.1 Clear all filters and ensure critical incidents exist'); incidentsPage.clearAllFilters(); - cy.log('3.2 Apply critical severity filter'); incidentsPage.toggleFilter('Critical'); - incidentsPage.elements.incidentsChartBarsGroups().should('have.length.greaterThan', 0); cy.log('3.3 Click on the first critical incident to select it by ID'); @@ -161,9 +157,12 @@ describe('Regression: Redux State Management', { tags: ['@incidents', '@incident cy.log('3.5 Verify both Critical and Incident ID chips are present'); incidentsPage.elements.filterChipValue('Critical').should('be.visible'); incidentsPage.elements.incidentIdFilterChip().should('be.visible'); - + cy.log('3.6 Deselect Critical and Apply Warning filter (which does not match the critical incident)'); + cy.wait(500); incidentsPage.toggleFilter('Critical'); + incidentsPage.elements.filterChipValue('Critical').should('not.exist'); + incidentsPage.toggleFilter('Warning'); cy.log('3.7 Verify incident is filtered out (no bars visible)'); @@ -177,7 +176,9 @@ describe('Regression: Redux State Management', { tags: ['@incidents', '@incident cy.log('SUCCESS: Incident ID filter was not removed when non-matching severity filter was added'); cy.log('3.9 Remove Warning filter and verify incident reappears'); - incidentsPage.toggleFilter('Warning'); + // Legacy path for quick rollback: + // incidentsPage.toggleFilter('Warning'); + incidentsPage.deselectFilterValue('Warning'); cy.log('3.10 With only Incident ID filter, incident should be visible again'); incidentsPage.elements.incidentsChartBarsGroups().should('have.length', 1); diff --git a/web/cypress/support/incidents_prometheus_query_mocks/prometheus-mocks.ts b/web/cypress/support/incidents_prometheus_query_mocks/prometheus-mocks.ts index bf35bb09d..ff77979d5 100644 --- a/web/cypress/support/incidents_prometheus_query_mocks/prometheus-mocks.ts +++ b/web/cypress/support/incidents_prometheus_query_mocks/prometheus-mocks.ts @@ -1,6 +1,7 @@ import { IncidentDefinition, PrometheusResponse, IncidentScenarioFixture } from './types'; import { createIncidentMock, createAlertDetailsMock } from './mock-generators'; import { convertFixtureToIncidents, parseYamlFixture } from './schema/fixture-converter'; +import { incidentsPage } from '../../views/incidents-page'; declare global { namespace Cypress { @@ -63,9 +64,15 @@ export function mockPrometheusQueryRange(incidents: IncidentDefinition[]): void console.log(`Responding with ${results.length} incident alerts from ${incidents.length} incidents`); req.reply(response); - }); + }).as('prometheusQueryMock'); } +/** + * Mock commands: register intercepts and navigate via goTo() to trigger a fresh data fetch. + * Using SPA navigation instead of cy.reload() avoids the dynamic-plugin chunk loading + * race condition that causes flaky empty-page failures in headless CI. + */ + Cypress.Commands.add('mockIncidents', (incidents: IncidentDefinition[]) => { cy.log(`=== SETTING UP INCIDENT MOCKING (${incidents.length} incidents) ===`); if (!Array.isArray(incidents)) { @@ -81,8 +88,7 @@ Cypress.Commands.add('mockIncidents', (incidents: IncidentDefinition[]) => { cy.log(`=== SETTING UP INCIDENT MOCKING (${incidents.length} incidents) ===`); mockPrometheusQueryRange(incidents); - // The mocking is not applied until the page is reloaded and the components fetch the new data - cy.reload(); + incidentsPage.goTo(); }); Cypress.Commands.add('mockIncidentFixture', (fixturePath: string) => { @@ -101,9 +107,8 @@ Cypress.Commands.add('mockIncidentFixture', (fixturePath: string) => { }); } - - // The mocking is not applied until the page is reloaded and the components fetch the new data - cy.reload(); + incidentsPage.goTo(); + cy.wait('@prometheusQueryMock', { timeout: 30000 }); }); Cypress.Commands.add('transformMetrics', () => { diff --git a/web/cypress/views/incidents-page.ts b/web/cypress/views/incidents-page.ts index 92cd8ca92..4142a63d3 100644 --- a/web/cypress/views/incidents-page.ts +++ b/web/cypress/views/incidents-page.ts @@ -154,42 +154,131 @@ export const incidentsPage = { cy.log('incidentsPage.goTo'); nav.sidenav.clickNavLink(['Observe', 'Alerting']); nav.tabs.switchTab('Incidents'); - + incidentsPage.elements.daysSelectToggle().should('be.visible'); }, setDays: (value: '1 day' | '3 days' | '7 days' | '15 days') => { cy.log('incidentsPage.setDays'); - incidentsPage.elements.daysSelectToggle().scrollIntoView().click(); const dayKey = value.replace(' ', '-'); cy.byTestID(`${DataTestIDs.IncidentsPage.DaysSelectOption}-${dayKey}`).should('be.visible').click(); incidentsPage.elements.daysSelectToggle().should('contain.text', value); }, + toggleFilterValueFromDropdown: ( + kind: 'severity' | 'state', + name: 'Critical' | 'Warning' | 'Informative' | 'Firing' | 'Resolved', + ) => { + const listSelector = kind === 'severity' + ? `[data-test="${DataTestIDs.IncidentsPage.FiltersSelectList}-severity"]` + : `[data-test="${DataTestIDs.IncidentsPage.FiltersSelectList}-state"]`; + + if (kind === 'severity') { + incidentsPage.elements.severityFilterToggle().click(); + incidentsPage.elements.severityFilterList().should('be.visible'); + cy.wait(250); + incidentsPage.elements.severityFilterOption(name as 'Critical' | 'Warning' | 'Informative').click(); + } else { + incidentsPage.elements.stateFilterToggle().click(); + incidentsPage.elements.stateFilterList().should('be.visible'); + cy.wait(250); + incidentsPage.elements.stateFilterOption(name as 'Firing' | 'Resolved').click(); + } + + // Always close the dropdown after selection and give the UI a moment to settle. + cy.get('body').type('{esc}'); + cy.wait(250); + cy.get('body').then(($updatedBody) => { + expect($updatedBody.find(listSelector).filter(':visible').length).to.equal(0); + }); + }, + + selectFilterValue: (name: 'Critical' | 'Warning' | 'Informative' | 'Firing' | 'Resolved') => { + cy.log(`incidentsPage.selectFilterValue: ${name}`); + cy.get('body').then(($body) => { + const chipExists = + $body + .find(`[data-test="${DataTestIDs.IncidentsPage.Toolbar}"] span`) + .filter((_, element) => Cypress.$(element).text().trim() === name).length > 0; + + if (!chipExists) { + incidentsPage.toggleFilter(name); + } + + incidentsPage.elements.filterChipValue(name).should('be.visible'); + }); + }, + + deselectFilterValue: (name: 'Critical' | 'Warning' | 'Informative' | 'Firing' | 'Resolved') => { + cy.log(`incidentsPage.deselectFilterValue: ${name}`); + const chipSelector = `[data-test="${DataTestIDs.IncidentsPage.Toolbar}"] span`; + const isChipPresent = ($body: JQuery) => + $body.find(chipSelector).filter((_, element) => Cypress.$(element).text().trim() === name).length > 0; + + cy.get('body').then(($body) => { + if (!isChipPresent($body)) { + incidentsPage.elements.toolbar().should('not.contain.text', name); + return; + } + + const attemptDeselect = (attempt: number) => { + cy.log(`Deselecting "${name}" via dropdown (attempt ${attempt})`); + incidentsPage.toggleFilter(name); + + return cy.get('body').then(($updatedBody) => { + if (!isChipPresent($updatedBody)) { + incidentsPage.elements.toolbar().should('not.contain.text', name); + return cy.wrap(undefined); + } + + if (attempt >= 2) { + throw new Error(`Failed to deselect "${name}" via dropdown after ${attempt} attempts`); + } + + cy.log( + `Retrying deselection for "${name}" because option click was visible but selection state did not change`, + ); + return attemptDeselect(attempt + 1); + }); + }; + + return attemptDeselect(1); + }); + }, + toggleFilter: (name: 'Critical' | 'Warning' | 'Informative' | 'Firing' | 'Resolved') => { cy.log('incidentsPage.toggleFilter'); - // Determine filter type based on the filter name const isSeverityFilter = ['Critical', 'Warning', 'Informative'].includes(name); const filterType = isSeverityFilter ? 'Severity' : 'State'; - - // Step 1: Select filter type if not already selected - incidentsPage.elements.filtersSelectToggle().click(); - incidentsPage.elements.filtersSelectOption(filterType).click(); - - // Step 2: Select the specific filter value - if (isSeverityFilter) { - incidentsPage.elements.severityFilterToggle().click(); - incidentsPage.elements.severityFilterOption(name).click(); - } else { - incidentsPage.elements.stateFilterToggle().click(); - incidentsPage.elements.stateFilterOption(name).click(); - } + const valueToggleSelector = isSeverityFilter + ? `[data-test="${DataTestIDs.IncidentsPage.FiltersSelectToggle}-severity"]` + : `[data-test="${DataTestIDs.IncidentsPage.FiltersSelectToggle}-state"]`; + + cy.wait(500); + + // If the value toggle is already visible (filter type already selected), skip + // re-selecting the filter type. Re-selecting triggers a React re-render and can + // leave PatternFly Select in a stale state where options render but ignore clicks. + cy.get('body').then(($body) => { + const isToggleVisible = $body.find(valueToggleSelector).filter(':visible').length > 0; + + if (!isToggleVisible) { + incidentsPage.elements.filtersSelectToggle().click(); + incidentsPage.elements.filtersSelectOption(filterType).click(); + } + + if (isSeverityFilter) { + incidentsPage.toggleFilterValueFromDropdown('severity', name); + } else { + incidentsPage.toggleFilterValueFromDropdown('state', name); + } + }); }, clearAllFilters: () => { cy.log('incidentsPage.clearAllFilters'); - incidentsPage.elements.clearAllFiltersButton().click({ force: true }); + incidentsPage.elements.clearAllFiltersButton().should('be.visible').click({ force: true }); }, removeFilter: (category: 'Severity' | 'State' | 'Incident ID', value: string) => { @@ -239,8 +328,6 @@ export const incidentsPage = { .click({ force: true }); }) .then(() => { - // The incident table loads the alerts for the previous incident first, then hides them and shows the alerts for the new incident - // This is why we need to wait for 2 seconds and can not use should or conditional testing semantics cy.wait(2000); return incidentsPage.elements.incidentsTable() .scrollIntoView() @@ -413,7 +500,7 @@ export const incidentsPage = { prepareIncidentsPageForSearch: () => { cy.log('incidentsPage.prepareIncidentsPageForSearch: Setting up page for search'); - cy.reload(); + incidentsPage.goTo(); incidentsPage.setDays(incidentsPage.SEARCH_CONFIG.DEFAULT_DAYS); incidentsPage.elements.incidentsChartContainer().should('be.visible'); cy.wait(incidentsPage.SEARCH_CONFIG.CHART_LOAD_WAIT); diff --git a/web/cypress/views/nav.ts b/web/cypress/views/nav.ts index b4543083e..16fab1abc 100644 --- a/web/cypress/views/nav.ts +++ b/web/cypress/views/nav.ts @@ -40,7 +40,7 @@ export const nav = { * @param tabname - The name of the tab to switch to */ switchTab: (tabname: string) => { - cy.get(Classes.HorizontalNav).contains(tabname).should('be.visible').click(); + cy.get(Classes.HorizontalNav).contains(tabname).should('be.visible').click({force: true}); cy.wait(2000); } } From 0ce64662290615e8c15dc498aa63672ced2e0b12 Mon Sep 17 00:00:00 2001 From: David Rajnoha Date: Thu, 19 Mar 2026 09:58:02 +0100 Subject: [PATCH 2/2] test: add regression tests for tooltip boundaries, stress testing, and permission denied handling New test files: - 02.reg_ui_tooltip_boundary_times.cy.ts: Mixed severity interval boundary times (OU-1205) and xfail test for start time offset bug (OU-1221) - 05.reg_stress_testing_ui.cy.ts: Stress testing with 100/200/500 alert fixtures to verify chart rendering performance and gap limits Additions to existing files: - 03.reg_api_calls.cy.ts: Permission denied handling test - verifies Incidents page shows access denied state on 403 responses (OU-1213) - prometheus-mocks.ts: mockPermissionDenied command for 403 mocking - incidents-page.ts: getIncidentBarVisibleSegments and hoverOverIncidentBarSegment helpers for multi-severity segment inspection Made-with: Cursor --- .../02.reg_ui_tooltip_boundary_times.cy.ts | 165 ++ .../regression/03.reg_api_calls.cy.ts | 50 +- .../regression/05.reg_stress_testing_ui.cy.ts | 96 + .../15-stress-test-100-alerts.yaml | 414 ++++ .../16-stress-test-200-alerts.yaml | 814 +++++++ .../17-stress-test-500-alerts.yaml | 2014 +++++++++++++++++ .../21-multi-severity-boundary-times.yaml | 38 + .../prometheus-mocks.ts | 53 + web/cypress/views/incidents-page.ts | 47 + 9 files changed, 3686 insertions(+), 5 deletions(-) create mode 100644 web/cypress/e2e/incidents/regression/02.reg_ui_tooltip_boundary_times.cy.ts create mode 100644 web/cypress/e2e/incidents/regression/05.reg_stress_testing_ui.cy.ts create mode 100644 web/cypress/fixtures/incident-scenarios/15-stress-test-100-alerts.yaml create mode 100644 web/cypress/fixtures/incident-scenarios/16-stress-test-200-alerts.yaml create mode 100644 web/cypress/fixtures/incident-scenarios/17-stress-test-500-alerts.yaml create mode 100644 web/cypress/fixtures/incident-scenarios/21-multi-severity-boundary-times.yaml diff --git a/web/cypress/e2e/incidents/regression/02.reg_ui_tooltip_boundary_times.cy.ts b/web/cypress/e2e/incidents/regression/02.reg_ui_tooltip_boundary_times.cy.ts new file mode 100644 index 000000000..8ad39e5ad --- /dev/null +++ b/web/cypress/e2e/incidents/regression/02.reg_ui_tooltip_boundary_times.cy.ts @@ -0,0 +1,165 @@ +/* +Regression test for mixed severity interval boundary times (Section 2.3.3). + +Test 1 (OU-1205): Verifies tooltip End times at severity interval boundaries +are rounded to 5-minute precision. Without rounding, consecutive interval end +times can land on non-5-minute values (e.g., "10:58" instead of "11:00"). + +Test 2 (OU-1221, XFAIL): Verifies Start times shown in incident tooltips match +alert tooltips and alerts table, and that consecutive segment boundaries align +with no 5-minute gap between End of one segment and Start of the next. +*/ + +import { incidentsPage } from '../../../views/incidents-page'; + +const MCP = { + namespace: Cypress.env('COO_NAMESPACE'), + packageName: 'cluster-observability-operator', + operatorName: 'Cluster Observability Operator', + config: { + kind: 'UIPlugin', + name: 'monitoring', + }, +}; + +const MP = { + namespace: 'openshift-monitoring', + operatorName: 'Cluster Monitoring Operator', +}; + +describe('Regression: Mixed Severity Interval Boundary Times', { tags: ['@incidents', '@xfail'] }, () => { + + before(() => { + cy.beforeBlockCOO(MCP, MP, { dashboards: false, troubleshootingPanel: false }); + }); + + beforeEach(() => { + cy.mockIncidentFixture('incident-scenarios/21-multi-severity-boundary-times.yaml'); + }); + + const extractTime = (tooltipText: string, field: 'Start' | 'End'): string => { + const afterField = tooltipText.split(field)[1] || ''; + const match = afterField.match(/(\d{1,2}:\d{2}(\s*[AP]M)?)/); + return match ? match[1].trim() : ''; + }; + + it('1. Tooltip End times at severity boundaries show 5-minute rounded values', () => { + const verifyEndTimeRounded = (label: string) => { + incidentsPage.elements.tooltip() + .invoke('text') + .then((text) => { + cy.log(`${label} tooltip: "${text}"`); + + if (text.match(/End.*---/)) { + cy.log(`${label}: Firing, End shows --- (skipped)`); + return; + } + + const endPart = text.split('End')[1]; + expect(endPart, `${label}: should contain End time`).to.exist; + + const timeMatch = endPart.match(/(\d{1,2}):(\d{2})/); + expect(timeMatch, `${label}: End time should be parseable`).to.not.be.null; + + const minutes = parseInt(timeMatch[2], 10); + const remainder = minutes % 5; + expect(remainder, `${label}: End minutes (${minutes}) should be divisible by 5, remainder=${remainder}`).to.equal(0); + cy.log(`${label}: End ${timeMatch[1]}:${timeMatch[2]} - minutes divisible by 5`); + }); + }; + + cy.log('1.1 Verify multi-severity incident loaded'); + incidentsPage.clearAllFilters(); + incidentsPage.setDays('1 day'); + incidentsPage.elements.incidentsChartContainer().should('be.visible'); + incidentsPage.elements.incidentsChartBarsGroups().should('have.length', 1); + + cy.log('1.2 Verify bar has multiple severity segments'); + incidentsPage.getIncidentBarVisibleSegments(0).then((segments) => { + expect(segments.length, 'Multi-severity bar should have at least 2 visible segments') + .to.be.greaterThan(1); + cy.log(`Found ${segments.length} visible severity segments`); + }); + + cy.log('1.3 Check first segment end time (Info -> Warning boundary)'); + incidentsPage.hoverOverIncidentBarSegment(0, 0); + verifyEndTimeRounded('First segment'); + + cy.log('1.4 Check second segment end time (Warning -> Critical boundary)'); + incidentsPage.hoverOverIncidentBarSegment(0, 1); + verifyEndTimeRounded('Second segment'); + + cy.log('1.5 Check third segment end time (Critical end)'); + incidentsPage.hoverOverIncidentBarSegment(0, 2); + verifyEndTimeRounded('Third segment'); + + cy.log('Verified: All tooltip End times at severity boundaries are at 5-minute precision (OU-1205)'); + }); + + it('2. Start times match between incident tooltip, alert tooltip, and table; consecutive boundaries align', + () => { + cy.log('2.1 Setup: verify multi-severity incident loaded'); + incidentsPage.clearAllFilters(); + incidentsPage.setDays('1 day'); + incidentsPage.elements.incidentsChartContainer().should('be.visible'); + incidentsPage.elements.incidentsChartBarsGroups().should('have.length', 1); + cy.pause(); + + cy.log('2.2 Consecutive interval boundaries: End of segment 1 should equal Start of segment 2'); + incidentsPage.hoverOverIncidentBarSegment(0, 0); + incidentsPage.elements.tooltip().invoke('text').then((firstText) => { + const firstEnd = extractTime(firstText, 'End'); + cy.log(`First segment End: ${firstEnd}`); + expect(firstEnd, 'First segment End should be parseable').to.not.be.empty; + + incidentsPage.hoverOverIncidentBarSegment(0, 1); + incidentsPage.elements.tooltip().invoke('text').then((secondText) => { + const secondStart = extractTime(secondText, 'Start'); + cy.log(`Second segment Start: ${secondStart}`); + expect(secondStart, 'Second segment Start should be parseable').to.not.be.empty; + expect(secondStart, + `No 5-min gap: second Start (${secondStart}) should equal first End (${firstEnd})` + ).to.equal(firstEnd); + }); + }); + cy.pause(); + + cy.log('2.3 Incident tooltip Start vs alert tooltip Start vs alerts table Start'); + incidentsPage.hoverOverIncidentBarSegment(0, 0); + incidentsPage.elements.tooltip().invoke('text').then((incidentText) => { + const incidentStart = extractTime(incidentText, 'Start'); + cy.log(`Incident tooltip Start: ${incidentStart}`); + expect(incidentStart, 'Incident Start should be parseable').to.not.be.empty; + + cy.log('2.4 Select incident and get alert tooltip Start'); + incidentsPage.selectIncidentById('monitoring-multi-severity-boundary-001'); + incidentsPage.elements.alertsChartCard().should('be.visible'); + + incidentsPage.hoverOverAlertBar(0); + incidentsPage.elements.alertsChartTooltip().invoke('text').then((alertText) => { + const alertStart = extractTime(alertText, 'Start'); + cy.log(`Alert tooltip Start: ${alertStart}`); + expect(incidentStart, + `Incident Start (${incidentStart}) should match alert Start (${alertStart})` + ).to.equal(alertStart); + }); + + cy.log('2.5 Compare incident tooltip Start with alerts table Start'); + incidentsPage.getSelectedIncidentAlerts().then((alerts) => { + expect(alerts.length, 'Should have at least 1 alert row').to.be.greaterThan(0); + alerts[0].getStartCell().invoke('text').then((cellText) => { + const tableMatch = cellText.trim().match(/(\d{1,2}:\d{2}(\s*[AP]M)?)/); + expect(tableMatch, 'Table Start time should be parseable').to.not.be.null; + const tableStart = tableMatch[1].trim(); + cy.log(`Alerts table Start: ${tableStart}`); + expect(incidentStart, + `Incident Start (${incidentStart}) should match table Start (${tableStart})` + ).to.equal(tableStart); + }); + }); + }); + cy.pause(); + + cy.log('Expected failure: Incident tooltip Start times are 5 minutes off (OU-1221)'); + }); +}); diff --git a/web/cypress/e2e/incidents/regression/03.reg_api_calls.cy.ts b/web/cypress/e2e/incidents/regression/03.reg_api_calls.cy.ts index 3d29c5f32..7fdb531b4 100644 --- a/web/cypress/e2e/incidents/regression/03.reg_api_calls.cy.ts +++ b/web/cypress/e2e/incidents/regression/03.reg_api_calls.cy.ts @@ -1,15 +1,20 @@ /* -Regression test for Silences Not Applied Correctly (Section 3.2) +Regression tests for API Calls and Data Loading (Section 3) -BUG: Silences were being matched by name only, not by name + namespace + severity. -This test verifies that silence matching uses: alertname + namespace + severity. +Tests: +1. Silences Not Applied Correctly (Section 3.2) + BUG: Silences were being matched by name only, not by name + namespace + severity. + This test verifies that silence matching uses: alertname + namespace + severity. -While targeting the bug, it verifies the basic Silences Implementation. +2. Permission Denied Handling (Section 3.5) + Tests graceful handling of 403 Forbidden responses from rules/silences endpoints. + Incidents page should still function when user lacks permissions to view rules/silences. -Verifies: OU-1020, OU-706 +Verifies: OU-1020, OU-706, OU-1213 */ import { incidentsPage } from '../../../views/incidents-page'; +import { nav } from '../../../views/nav'; const MCP = { namespace: Cypress.env('COO_NAMESPACE'), @@ -123,4 +128,39 @@ describe('Regression: Silences Not Applied Correctly', { tags: ['@incidents'] }, }); }); +describe('Regression: Permission Denied Handling', { tags: ['@incidents'] }, () => { + before(() => { + cy.beforeBlockCOO(MCP, MP, { dashboards: false, troubleshootingPanel: false }); + }); + + beforeEach(() => { + cy.log('Mock all API endpoints as 403 Forbidden'); + cy.mockPermissionDenied(); + cy.log('Navigate to Observe -> Incidents'); + // Using custom navigation commands to avoid waiting for the page to load which never happens in this test + nav.sidenav.clickNavLink(['Observe', 'Alerting']); + nav.tabs.switchTab('Incidents'); + + }); + + it('Page displays access denied state when all API endpoints return 403 Forbidden', () => { + cy.log('1.1 Verify 403 requests were intercepted'); + const waitTimeout = { timeout: 120000 }; + cy.wait('@rulesPermissionDenied', waitTimeout) + .its('response').should('exist') + .its('statusCode').should('eq', 403); + cy.wait('@silencesPermissionDenied', waitTimeout) + .its('response').should('exist') + .its('statusCode').should('eq', 403); + cy.wait('@prometheusQueryRangePermissionDenied', waitTimeout) + .its('response').should('exist') + .its('statusCode').should('eq', 403); + + cy.log('1.2 Verify access denied empty state is displayed'); + cy.byTestID('access-denied').should('be.visible'); + cy.byTestID('access-denied').should('contain.text', 'You don\'t have access to this section due to cluster policy'); + + cy.log('Verified: Page displays restricted access state for permission denied'); + }); +}); diff --git a/web/cypress/e2e/incidents/regression/05.reg_stress_testing_ui.cy.ts b/web/cypress/e2e/incidents/regression/05.reg_stress_testing_ui.cy.ts new file mode 100644 index 000000000..47bc455d7 --- /dev/null +++ b/web/cypress/e2e/incidents/regression/05.reg_stress_testing_ui.cy.ts @@ -0,0 +1,96 @@ +/* +Regression tests for UI issues that manifest under stress conditions (high alert/incident counts). + +Section 5.1: Alerts chart padding with 100+ alerts (OU-1123) + - Height calculation should not produce excessive padding pushing bars below the visible area. + - A smaller gap with ~500+ alerts is accepted as a known limitation. + +Note: Stress fixtures use a short timeline (1h) to avoid a known Math.max/min call stack +overflow when many alerts share a group_id with long timelines. The padding behavior under +test is independent of timeline length. See WIP.stress-test-1000-alerts.cy.ts to reproduce +the overflow with the original 5d timeline. +*/ + +import { incidentsPage } from '../../../views/incidents-page'; + +const MCP = { + namespace: Cypress.env('COO_NAMESPACE'), + packageName: 'cluster-observability-operator', + operatorName: 'Cluster Observability Operator', + config: { + kind: 'UIPlugin', + name: 'monitoring', + }, +}; + +const MP = { + namespace: 'openshift-monitoring', + operatorName: 'Cluster Monitoring Operator', +}; + +const MAX_GAP_STANDARD = 250; +const MAX_GAP_RELAXED = 500; + +describe('Regression: Stress Testing UI', { tags: ['@incidents'] }, () => { + + before(() => { + cy.beforeBlockCOO(MCP, MP, { dashboards: false, troubleshootingPanel: false }); + }); + + it('5.1 No excessive padding between chart top and alert bars for 100, 200, and 500 alerts', () => { + const verifyAlertBarPadding = ( + fixtureFile: string, + incidentId: string, + maxGap: number, + label: string + ) => { + cy.mockIncidentFixture(`incident-scenarios/${fixtureFile}`); + incidentsPage.clearAllFilters(); + incidentsPage.setDays('1 day'); + + incidentsPage.elements.incidentsChartBarsGroups().should('have.length', 1); + incidentsPage.selectIncidentById(incidentId); + + incidentsPage.elements.alertsChartCard().should('be.visible'); + incidentsPage.elements.alertsChartBarsVisiblePaths() + .should('have.length.greaterThan', 0); + + incidentsPage.elements.alertsChartContainer().first().scrollIntoView(); + incidentsPage.elements.alertsChartContainer().first().then(($container) => { + const containerTop = $container[0].getBoundingClientRect().top; + incidentsPage.getAlertBarRect(0).then((barRect) => { + const gap = barRect.top - containerTop; + cy.log(`${label}: Gap between container top and first alert bar = ${gap}px`); + expect(gap, `${label}: first alert bar should start near chart top`).to.be.lessThan(maxGap); + expect(gap, `${label}: gap should be non-negative`).to.be.at.least(0); + }); + }); + }; + + cy.log('5.1.1 Verify no excessive padding with 100 alerts'); + verifyAlertBarPadding( + '15-stress-test-100-alerts.yaml', + 'cluster-wide-failure-100-alerts', + MAX_GAP_STANDARD, + '100 alerts' + ); + + cy.log('5.1.2 Verify no excessive padding with 200 alerts'); + verifyAlertBarPadding( + '16-stress-test-200-alerts.yaml', + 'cluster-wide-failure-200-alerts', + MAX_GAP_STANDARD, + '200 alerts' + ); + + cy.log('5.1.3 Verify accepted limitation with 500 alerts (relaxed threshold)'); + verifyAlertBarPadding( + '17-stress-test-500-alerts.yaml', + 'cluster-wide-failure-500-alerts', + MAX_GAP_RELAXED, + '500 alerts' + ); + + cy.log('Verified: Alert bars have no excessive padding for 100, 200, and 500 alerts'); + }); +}); diff --git a/web/cypress/fixtures/incident-scenarios/15-stress-test-100-alerts.yaml b/web/cypress/fixtures/incident-scenarios/15-stress-test-100-alerts.yaml new file mode 100644 index 000000000..1e350ed2d --- /dev/null +++ b/web/cypress/fixtures/incident-scenarios/15-stress-test-100-alerts.yaml @@ -0,0 +1,414 @@ +name: "15 - UI Stress Test - 100 Alerts" +description: Stress test scenario with single incident containing 100 alerts +incidents: +- id: cluster-wide-failure-100-alerts + component: monitoring + layer: core + timeline: + start: 1h + severityChanges: + - time: 1h + severity: warning + - time: 30m + severity: critical + alerts: + - name: NetworkPolicyViolation001 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation002 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation003 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation004 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation005 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation006 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation007 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation008 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation009 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation010 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation011 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation012 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation013 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation014 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation015 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation016 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation017 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation018 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation019 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation020 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation021 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation022 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation023 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation024 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation025 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation026 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation027 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation028 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation029 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation030 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation031 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation032 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation033 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation034 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation035 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation036 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation037 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation038 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation039 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation040 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation041 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation042 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation043 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation044 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation045 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation046 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation047 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation048 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation049 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation050 + namespace: openshift-network + severity: critical + firing: true + - name: SDNControllerDown051 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown052 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown053 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown054 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown055 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown056 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown057 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown058 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown059 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown060 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown061 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown062 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown063 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown064 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown065 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown066 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown067 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown068 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown069 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown070 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown071 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown072 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown073 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown074 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown075 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown076 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown077 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown078 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown079 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown080 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown081 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown082 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown083 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown084 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown085 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown086 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown087 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown088 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown089 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown090 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown091 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown092 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown093 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown094 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown095 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown096 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown097 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown098 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown099 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown100 + namespace: openshift-sdn + severity: critical + firing: true diff --git a/web/cypress/fixtures/incident-scenarios/16-stress-test-200-alerts.yaml b/web/cypress/fixtures/incident-scenarios/16-stress-test-200-alerts.yaml new file mode 100644 index 000000000..de3354145 --- /dev/null +++ b/web/cypress/fixtures/incident-scenarios/16-stress-test-200-alerts.yaml @@ -0,0 +1,814 @@ +name: "16 - UI Stress Test - 200 Alerts" +description: Stress test scenario with single incident containing 200 alerts +incidents: +- id: cluster-wide-failure-200-alerts + component: monitoring + layer: core + timeline: + start: 1h + severityChanges: + - time: 1h + severity: warning + - time: 30m + severity: critical + alerts: + - name: NetworkPolicyViolation001 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation002 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation003 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation004 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation005 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation006 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation007 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation008 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation009 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation010 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation011 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation012 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation013 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation014 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation015 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation016 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation017 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation018 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation019 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation020 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation021 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation022 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation023 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation024 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation025 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation026 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation027 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation028 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation029 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation030 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation031 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation032 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation033 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation034 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation035 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation036 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation037 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation038 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation039 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation040 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation041 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation042 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation043 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation044 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation045 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation046 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation047 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation048 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation049 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation050 + namespace: openshift-network + severity: critical + firing: true + - name: SDNControllerDown051 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown052 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown053 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown054 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown055 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown056 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown057 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown058 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown059 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown060 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown061 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown062 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown063 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown064 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown065 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown066 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown067 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown068 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown069 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown070 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown071 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown072 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown073 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown074 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown075 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown076 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown077 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown078 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown079 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown080 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown081 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown082 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown083 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown084 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown085 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown086 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown087 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown088 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown089 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown090 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown091 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown092 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown093 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown094 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown095 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown096 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown097 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown098 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown099 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown100 + namespace: openshift-sdn + severity: critical + firing: true + - name: OVNKubeControllerDown101 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown102 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown103 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown104 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown105 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown106 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown107 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown108 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown109 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown110 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown111 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown112 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown113 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown114 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown115 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown116 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown117 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown118 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown119 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown120 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown121 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown122 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown123 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown124 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown125 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown126 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown127 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown128 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown129 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown130 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown131 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown132 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown133 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown134 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown135 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown136 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown137 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown138 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown139 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown140 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown141 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown142 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown143 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown144 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown145 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown146 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown147 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown148 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown149 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown150 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: NodeNetworkUnavailable151 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable152 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable153 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable154 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable155 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable156 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable157 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable158 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable159 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable160 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable161 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable162 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable163 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable164 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable165 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable166 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable167 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable168 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable169 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable170 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable171 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable172 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable173 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable174 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable175 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable176 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable177 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable178 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable179 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable180 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable181 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable182 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable183 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable184 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable185 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable186 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable187 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable188 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable189 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable190 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable191 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable192 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable193 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable194 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable195 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable196 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable197 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable198 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable199 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable200 + namespace: openshift-network + severity: warning + firing: true diff --git a/web/cypress/fixtures/incident-scenarios/17-stress-test-500-alerts.yaml b/web/cypress/fixtures/incident-scenarios/17-stress-test-500-alerts.yaml new file mode 100644 index 000000000..7bc365733 --- /dev/null +++ b/web/cypress/fixtures/incident-scenarios/17-stress-test-500-alerts.yaml @@ -0,0 +1,2014 @@ +name: UI Stress Test - 500 Alerts +description: Stress test scenario with single incident containing 500 alerts +incidents: +- id: cluster-wide-failure-500-alerts + component: monitoring + layer: core + timeline: + start: 1h + severityChanges: + - time: 1h + severity: warning + - time: 30m + severity: critical + alerts: + - name: NetworkPolicyViolation001 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation002 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation003 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation004 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation005 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation006 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation007 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation008 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation009 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation010 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation011 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation012 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation013 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation014 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation015 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation016 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation017 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation018 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation019 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation020 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation021 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation022 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation023 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation024 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation025 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation026 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation027 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation028 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation029 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation030 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation031 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation032 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation033 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation034 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation035 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation036 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation037 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation038 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation039 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation040 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation041 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation042 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation043 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation044 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation045 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation046 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation047 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation048 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation049 + namespace: openshift-network + severity: critical + firing: true + - name: NetworkPolicyViolation050 + namespace: openshift-network + severity: critical + firing: true + - name: SDNControllerDown051 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown052 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown053 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown054 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown055 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown056 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown057 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown058 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown059 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown060 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown061 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown062 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown063 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown064 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown065 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown066 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown067 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown068 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown069 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown070 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown071 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown072 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown073 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown074 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown075 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown076 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown077 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown078 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown079 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown080 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown081 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown082 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown083 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown084 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown085 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown086 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown087 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown088 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown089 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown090 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown091 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown092 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown093 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown094 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown095 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown096 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown097 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown098 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown099 + namespace: openshift-sdn + severity: critical + firing: true + - name: SDNControllerDown100 + namespace: openshift-sdn + severity: critical + firing: true + - name: OVNKubeControllerDown101 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown102 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown103 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown104 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown105 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown106 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown107 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown108 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown109 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown110 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown111 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown112 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown113 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown114 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown115 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown116 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown117 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown118 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown119 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown120 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown121 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown122 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown123 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown124 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown125 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown126 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown127 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown128 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown129 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown130 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown131 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown132 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown133 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown134 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown135 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown136 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown137 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown138 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown139 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown140 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown141 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown142 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown143 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown144 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown145 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown146 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown147 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown148 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown149 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: OVNKubeControllerDown150 + namespace: openshift-ovn-kubernetes + severity: critical + firing: true + - name: NodeNetworkUnavailable151 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable152 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable153 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable154 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable155 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable156 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable157 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable158 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable159 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable160 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable161 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable162 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable163 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable164 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable165 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable166 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable167 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable168 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable169 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable170 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable171 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable172 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable173 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable174 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable175 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable176 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable177 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable178 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable179 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable180 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable181 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable182 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable183 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable184 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable185 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable186 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable187 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable188 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable189 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable190 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable191 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable192 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable193 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable194 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable195 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable196 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable197 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable198 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable199 + namespace: openshift-network + severity: warning + firing: true + - name: NodeNetworkUnavailable200 + namespace: openshift-network + severity: warning + firing: true + - name: IngressControllerDegraded201 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded202 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded203 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded204 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded205 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded206 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded207 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded208 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded209 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded210 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded211 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded212 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded213 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded214 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded215 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded216 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded217 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded218 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded219 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded220 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded221 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded222 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded223 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded224 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded225 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded226 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded227 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded228 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded229 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded230 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded231 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded232 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded233 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded234 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded235 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded236 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded237 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded238 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded239 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded240 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded241 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded242 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded243 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded244 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded245 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded246 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded247 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded248 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded249 + namespace: openshift-ingress + severity: warning + firing: true + - name: IngressControllerDegraded250 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency251 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency252 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency253 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency254 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency255 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency256 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency257 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency258 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency259 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency260 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency261 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency262 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency263 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency264 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency265 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency266 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency267 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency268 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency269 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency270 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency271 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency272 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency273 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency274 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency275 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency276 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency277 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency278 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency279 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency280 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency281 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency282 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency283 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency284 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency285 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency286 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency287 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency288 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency289 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency290 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency291 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency292 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency293 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency294 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency295 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency296 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency297 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency298 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency299 + namespace: openshift-ingress + severity: warning + firing: true + - name: RouterHighLatency300 + namespace: openshift-ingress + severity: warning + firing: true + - name: DNSOperatorDegraded301 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded302 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded303 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded304 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded305 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded306 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded307 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded308 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded309 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded310 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded311 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded312 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded313 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded314 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded315 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded316 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded317 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded318 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded319 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded320 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded321 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded322 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded323 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded324 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded325 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded326 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded327 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded328 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded329 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded330 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded331 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded332 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded333 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded334 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded335 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded336 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded337 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded338 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded339 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded340 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded341 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded342 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded343 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded344 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded345 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded346 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded347 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded348 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded349 + namespace: openshift-dns + severity: critical + firing: true + - name: DNSOperatorDegraded350 + namespace: openshift-dns + severity: critical + firing: true + - name: CoreDNSLatencyHigh351 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh352 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh353 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh354 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh355 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh356 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh357 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh358 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh359 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh360 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh361 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh362 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh363 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh364 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh365 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh366 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh367 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh368 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh369 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh370 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh371 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh372 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh373 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh374 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh375 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh376 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh377 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh378 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh379 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh380 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh381 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh382 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh383 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh384 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh385 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh386 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh387 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh388 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh389 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh390 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh391 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh392 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh393 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh394 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh395 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh396 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh397 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh398 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh399 + namespace: openshift-dns + severity: warning + firing: true + - name: CoreDNSLatencyHigh400 + namespace: openshift-dns + severity: warning + firing: true + - name: KubeNodeNotReady401 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady402 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady403 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady404 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady405 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady406 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady407 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady408 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady409 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady410 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady411 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady412 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady413 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady414 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady415 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady416 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady417 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady418 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady419 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady420 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady421 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady422 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady423 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady424 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady425 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady426 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady427 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady428 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady429 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady430 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady431 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady432 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady433 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady434 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady435 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady436 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady437 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady438 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady439 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady440 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady441 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady442 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady443 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady444 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady445 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady446 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady447 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady448 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady449 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubeNodeNotReady450 + namespace: openshift-monitoring + severity: critical + firing: true + - name: KubePodNotReady451 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady452 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady453 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady454 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady455 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady456 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady457 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady458 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady459 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady460 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady461 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady462 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady463 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady464 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady465 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady466 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady467 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady468 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady469 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady470 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady471 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady472 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady473 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady474 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady475 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady476 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady477 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady478 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady479 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady480 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady481 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady482 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady483 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady484 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady485 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady486 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady487 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady488 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady489 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady490 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady491 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady492 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady493 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady494 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady495 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady496 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady497 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady498 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady499 + namespace: openshift-monitoring + severity: warning + firing: true + - name: KubePodNotReady500 + namespace: openshift-monitoring + severity: warning + firing: true diff --git a/web/cypress/fixtures/incident-scenarios/21-multi-severity-boundary-times.yaml b/web/cypress/fixtures/incident-scenarios/21-multi-severity-boundary-times.yaml new file mode 100644 index 000000000..7852e3c6c --- /dev/null +++ b/web/cypress/fixtures/incident-scenarios/21-multi-severity-boundary-times.yaml @@ -0,0 +1,38 @@ +name: "Multi-Severity Interval Boundary Times" +description: "Single resolved multi-severity incident for verifying that tooltip end times at severity interval boundaries are 5-minute rounded. The incident escalates from info to warning to critical over 5 hours." +incidents: + - id: "monitoring-multi-severity-boundary-001" + component: "monitoring" + layer: "core" + timeline: + start: "6h" + end: "1h" + severityChanges: + - time: "6h" + severity: "info" + - time: "4h" + severity: "warning" + - time: "2h" + severity: "critical" + alerts: + - name: "MonitoringLatencyHigh001" + namespace: "openshift-monitoring" + severity: "info" + firing: false + timeline: + start: "6h" + end: "4h" + - name: "MonitoringDegraded001" + namespace: "openshift-monitoring" + severity: "warning" + firing: false + timeline: + start: "4h" + end: "2h" + - name: "MonitoringDown001" + namespace: "openshift-monitoring" + severity: "critical" + firing: false + timeline: + start: "2h" + end: "1h" diff --git a/web/cypress/support/incidents_prometheus_query_mocks/prometheus-mocks.ts b/web/cypress/support/incidents_prometheus_query_mocks/prometheus-mocks.ts index ff77979d5..4e57a0e6b 100644 --- a/web/cypress/support/incidents_prometheus_query_mocks/prometheus-mocks.ts +++ b/web/cypress/support/incidents_prometheus_query_mocks/prometheus-mocks.ts @@ -9,10 +9,17 @@ declare global { mockIncidents(incidents: IncidentDefinition[]): Chainable; mockIncidentFixture(fixturePath: string): Chainable; transformMetrics(): Chainable; + mockPermissionDenied(endpoints?: PermissionDeniedEndpoints): Chainable; } } } +export interface PermissionDeniedEndpoints { + rules?: boolean; + silences?: boolean; + prometheus?: boolean; +} + export const NEW_METRIC_NAME = 'cluster_health_components_map'; export const OLD_METRIC_NAME = 'cluster:health:components:map'; const MOCK_QUERY = '/api/prometheus/api/v1/query_range*'; @@ -152,4 +159,50 @@ Cypress.Commands.add('transformMetrics', () => { req.continue(); } }); +}); + +export function mockPermissionDeniedResponses(endpoints: PermissionDeniedEndpoints = {}): void { + const { rules = true, silences = true, prometheus = true } = endpoints; + + const forbiddenResponse = { + statusCode: 403, + body: 'Forbidden', + headers: { + 'content-type': 'text/plain' + } + }; + + if (rules) { + cy.intercept('GET', '/api/prometheus/api/v1/rules*', (req) => { + Cypress.log({ name: '403', message: `${req.method} ${req.url}` }); + req.reply(forbiddenResponse); + }).as('rulesPermissionDenied'); + cy.log('Mocking /api/prometheus/api/v1/rules as 403 Forbidden'); + } + + if (silences) { + cy.intercept('GET', '/api/alertmanager/api/v2/silences*', (req) => { + Cypress.log({ name: '403', message: `${req.method} ${req.url}` }); + req.reply(forbiddenResponse); + }).as('silencesPermissionDenied'); + cy.log('Mocking /api/alertmanager/api/v2/silences as 403 Forbidden'); + } + + if (prometheus) { + cy.intercept('GET', MOCK_QUERY, (req) => { + Cypress.log({ name: '403', message: `${req.method} ${req.url}` }); + req.reply(forbiddenResponse); + }).as('prometheusQueryRangePermissionDenied'); + + cy.intercept('GET', /\/api\/prometheus\/api\/v1\/query\?.*/, (req) => { + Cypress.log({ name: '403', message: `${req.method} ${req.url}` }); + req.reply(forbiddenResponse); + }).as('prometheusQueryInstantPermissionDenied'); + cy.log('Mocking all Prometheus query endpoints as 403 Forbidden'); + } +} + +Cypress.Commands.add('mockPermissionDenied', (endpoints: PermissionDeniedEndpoints = {}) => { + cy.log('=== SETTING UP PERMISSION DENIED MOCKS ==='); + mockPermissionDeniedResponses(endpoints); }); \ No newline at end of file diff --git a/web/cypress/views/incidents-page.ts b/web/cypress/views/incidents-page.ts index 4142a63d3..c241897b4 100644 --- a/web/cypress/views/incidents-page.ts +++ b/web/cypress/views/incidents-page.ts @@ -437,6 +437,53 @@ export const incidentsPage = { return incidentsPage.waitForTooltip(); }, + /** + * Returns the visible (non-nodata) path elements within a single incident bar group. + * Useful for multi-severity incidents where each severity segment is a separate path. + * + * @param barIndex - Zero-based index of the incident bar group + * @returns Chainable resolving to a jQuery set of visible path elements + */ + getIncidentBarVisibleSegments: (barIndex: number) => { + cy.log(`incidentsPage.getIncidentBarVisibleSegments: ${barIndex}`); + return incidentsPage.elements.incidentsChartBarsGroups().eq(barIndex) + .find('path[role="presentation"]') + .then(($paths) => { + return $paths.filter((_, el) => { + const opacity = Cypress.$(el).css('fill-opacity') || Cypress.$(el).attr('fill-opacity'); + return parseFloat(opacity || '0') > 0; + }); + }); + }, + + /** + * Hovers over a specific severity segment within an incident bar group to trigger its tooltip. + * Unlike hoverOverIncidentBar (which always targets the first visible path), + * this method lets you target any segment by index within a multi-severity bar. + * + * @param barIndex - Zero-based index of the incident bar group + * @param segmentIndex - Zero-based index of the visible segment within that bar + */ + hoverOverIncidentBarSegment: (barIndex: number, segmentIndex: number) => { + cy.log(`incidentsPage.hoverOverIncidentBarSegment: bar=${barIndex}, segment=${segmentIndex}`); + incidentsPage.getIncidentBarVisibleSegments(barIndex).then((segments) => { + if (segmentIndex >= segments.length) { + throw new Error(`Segment ${segmentIndex} not found (only ${segments.length} visible segments in bar ${barIndex})`); + } + const path = segments[segmentIndex]; + const rect = path.getBoundingClientRect(); + incidentsPage.elements.incidentsChartSvg() + .first() + .trigger('mousemove', { + clientX: rect.left + rect.width / 2, + clientY: rect.top + rect.height / 2, + force: true, + }) + .wait(200); + }); + return incidentsPage.waitForTooltip(); + }, + getIncidentBarRect: (index: number) => { cy.log(`incidentsPage.getIncidentBarRect: ${index}`); return incidentsPage.elements.incidentsChartBarsGroups()