Skip to content
9 changes: 6 additions & 3 deletions web/cypress/e2e/incidents/00.coo_incidents_e2e.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,15 @@ describe('BVT: Incidents - e2e', { tags: ['@smoke', '@slow', '@incidents', '@e2e
incidentsPage.clearAllFilters();

const intervalMs = 60_000;
const maxMinutes = 30;

cy.log('1.2 Wait for incident with custom alert to appear');
// Poll via UI traversal with OOM-safe findIncidentWithAlert.
// The search loop has two layers of OOM protection:
// 1. _quietSearch — suppresses Cypress DOM snapshots
// 2. Hard timeout (35 min) — kills infinite loops
cy.waitUntil(() => incidentsPage.findIncidentWithAlert(currentAlertName), {
interval: intervalMs,
timeout: maxMinutes * intervalMs,
interval: 2 * intervalMs,
timeout: 30 * intervalMs + 2 * intervalMs,
});

cy.log('1.3 Verify custom alert appears in alerts table');
Expand Down
48 changes: 48 additions & 0 deletions web/cypress/e2e/incidents/01.incidents.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const MP = {
describe('BVT: Incidents - UI', { tags: ['@smoke', '@incidents'] }, () => {
before(() => {
cy.beforeBlockCOO(MCP, MP, { dashboards: false, troubleshootingPanel: false });
incidentsPage.warmUpForPlugin();
cy.mockIncidentFixture(
'incident-scenarios/1-single-incident-firing-critical-and-warning-alerts.yaml',
);
Expand Down Expand Up @@ -88,6 +89,53 @@ describe('BVT: Incidents - UI', { tags: ['@smoke', '@incidents'] }, () => {

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.clearAllFilters();
incidentsPage.findIncidentWithAlert('TargetAlert').should('be.true');
});

it('6. Admin perspective - Incidents page - Bar click selection walkthrough', () => {
cy.log('6.1 Load multi-incident fixture and verify chart bars are clickable');
cy.mockIncidentFixture(
'incident-scenarios/1-single-incident-firing-critical-and-warning-alerts.yaml',
);
incidentsPage.goTo();
incidentsPage.clearAllFilters();
incidentsPage.setDays('7 days');
incidentsPage.elements.incidentsChartContainer().should('be.visible');

cy.log('6.2 Select incident bar and verify table appears with expected alerts');
incidentsPage.selectIncidentByBarIndex(0);
incidentsPage.elements.incidentsTable().should('be.visible');
incidentsPage.elements.incidentsTableComponentCell(0).should('contain.text', 'monitoring');
incidentsPage.expandRow(0);
incidentsPage.elements.incidentsDetailsTable().should('be.visible');
incidentsPage.elements.incidentsDetailsAlertRuleCell(0).should('be.visible');
incidentsPage.elements
.incidentsDetailsTable()
.should('contain.text', 'AlertmanagerReceiversNotConfigured');
incidentsPage.elements
.incidentsDetailsTable()
.should('contain.text', 'KubeDeploymentReplicasMismatch');
incidentsPage.elements.incidentsDetailsTable().should('contain.text', 'KubePodCrashLooping');

cy.log('6.3 Deselect incident bar and verify table disappears');
incidentsPage.deselectIncidentByBar(0);
incidentsPage.elements.incidentsTable().should('not.exist');

cy.log('6.4 Select by incident ID and verify table appears with expected alerts');
incidentsPage.selectIncidentById('monitoring-critical-001');
incidentsPage.elements.incidentsTable().should('be.visible');
incidentsPage.expandRow(0);
incidentsPage.elements
.incidentsDetailsTable()
.should('contain.text', 'AlertmanagerReceiversNotConfigured');
incidentsPage.elements
.incidentsDetailsTable()
.should('contain.text', 'KubeDeploymentReplicasMismatch');
incidentsPage.elements.incidentsDetailsTable().should('contain.text', 'KubePodCrashLooping');

cy.log('6.5 Deselect by incident ID and verify table disappears');
incidentsPage.deselectIncidentById('monitoring-critical-001');
incidentsPage.elements.incidentsTable().should('not.exist');
});
});
55 changes: 51 additions & 4 deletions web/cypress/e2e/incidents/regression/01.reg_filtering.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,54 @@ describe('Regression: Incidents Filtering', { tags: ['@incidents'] }, () => {
incidentsPage.clearAllFilters();
});

it('2. Chart interaction with active filters', () => {
it('2. Incident ID filter - select, verify, and traverse', () => {
cy.log('2.1 Clear filters and verify all incidents are loaded');
incidentsPage.clearAllFilters();
incidentsPage.elements.incidentsChartBarsGroups().should('have.length', 12);

cy.log('2.2 Discover all incident IDs from the filter dropdown');
incidentsPage.getIncidentIds().then((ids) => {
expect(ids.length).to.equal(12);
cy.log(`Discovered ${ids.length} incident IDs`);

cy.log('2.3 Select an incident by ID filter and verify table appears');
incidentsPage.selectIncidentIdFilter(ids[0]);
incidentsPage.elements.incidentsTable().should('be.visible');
incidentsPage.elements.incidentsChartBarsGroups().should('have.length', 1);

cy.log('2.4 Clear the Incident ID filter and verify all incidents return');
incidentsPage.clearAllFilters();
incidentsPage.elements.incidentsTable().should('not.exist');
incidentsPage.elements.incidentsChartBarsGroups().should('have.length', 12);

cy.log('2.5 Filter-based traversal finds a known alert');
cy.mockIncidentFixture('incident-scenarios/6-multi-incident-target-alert-scenario.yaml');
incidentsPage.clearAllFilters();
incidentsPage.setDays('7 days');
incidentsPage.findIncidentWithAlert('TargetAlert').should('be.true');

cy.log('2.6 Filter-based traversal returns false for non-existent alert');
incidentsPage.findIncidentWithAlert('NonExistentAlert').should('be.false');
});

cy.log('2.7 Select incident by ID filter and verify matching alerts are present');
cy.mockIncidentFixture('incident-scenarios/7-comprehensive-filtering-test-scenarios.yaml');
incidentsPage.clearAllFilters();
incidentsPage.selectIncidentIdFilter('etcd-critical-warning-001');
incidentsPage.elements.incidentsTable().should('be.visible');
incidentsPage.elements.incidentsTableComponentCell(0).should('contain.text', 'etcd');
incidentsPage.expandRow(0);
incidentsPage.elements.incidentsDetailsTable().should('be.visible');
incidentsPage.elements
.incidentsDetailsTable()
.should('contain.text', 'EtcdClusterUnavailable001');
incidentsPage.elements.incidentsDetailsTable().should('contain.text', 'EtcdHighLatency001');
incidentsPage.elements.incidentsDetailsTable().should('contain.text', 'EtcdBackupFailed001');

incidentsPage.clearAllFilters();
});

it('3. Chart interaction with active filters', () => {
cy.log('Setting up filters for chart interaction testing');
incidentsPage.clearAllFilters();

Expand All @@ -120,16 +167,16 @@ describe('Regression: Incidents Filtering', { tags: ['@incidents'] }, () => {
incidentsPage.elements.incidentsChartBarsGroups().should('have.length', 2);
cy.log('Setup complete: Informative + Firing filters active, 2 incidents shown');

cy.log('2.1 Select incident bar while filters are active');
cy.log('3.1 Select incident bar while filters are active');
incidentsPage.selectIncidentByBarIndex(0);
incidentsPage.elements.incidentsTable().should('be.visible');
cy.log('Incident table displayed after bar selection');

cy.log('2.2 Verify just selected incident is shown in the chart');
cy.log('3.2 Verify just selected incident is shown in the chart');
incidentsPage.elements.incidentsChartBarsGroups().should('have.length', 1);
cy.log('Verified: 1 incident shown');

cy.log('2.3 Deselect incident bar and verify filter persistence');
cy.log('3.3 Deselect incident bar and verify filter persistence');
incidentsPage.deselectIncidentByBar();
incidentsPage.elements.incidentsTable().should('not.exist');
incidentsPage.elements.incidentsChartBarsGroups().should('have.length', 2);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ const MP = {
describe('Regression: Charts UI - Comprehensive', { tags: ['@incidents'] }, () => {
before(() => {
cy.beforeBlockCOO(MCP, MP, { dashboards: false, troubleshootingPanel: false });
incidentsPage.warmUpForPlugin();
});

beforeEach(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ describe(
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',
Expand Down Expand Up @@ -141,7 +140,6 @@ describe(
).to.equal(firstEnd);
});
});
cy.pause();

cy.log('2.3 Incident tooltip Start vs alert tooltip Start vs alerts table Start');
incidentsPage.hoverOverIncidentBarSegment(0, 0);
Expand Down Expand Up @@ -188,7 +186,6 @@ describe(
});
});
});
cy.pause();

cy.log('Expected failure: Incident tooltip Start times are 5 minutes off (OU-1221)');
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ describe(

before(() => {
cy.beforeBlockCOO(MCP, MP, { dashboards: false, troubleshootingPanel: false });
incidentsPage.warmUpForPlugin();

// Reset the search timeout so this spec gets a fresh 35-minute window
incidentsPage.resetSearchTimeout();
Comment thread
coderabbitai[bot] marked this conversation as resolved.

cy.log('Create firing alert for testing');
cy.cleanupIncidentPrometheusRules();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const MP = {
describe('Regression: Silences Not Applied Correctly', { tags: ['@incidents'] }, () => {
before(() => {
cy.beforeBlockCOO(MCP, MP, { dashboards: false, troubleshootingPanel: false });
incidentsPage.warmUpForPlugin();
});

beforeEach(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const MP = {
describe('Regression: Redux State Management', { tags: ['@incidents', '@incidents-redux'] }, () => {
before(() => {
cy.beforeBlockCOO(MCP, MP, { dashboards: false, troubleshootingPanel: false });
incidentsPage.warmUpForPlugin();
});

beforeEach(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const MAX_GAP_RELAXED = 500;
describe('Regression: Stress Testing UI', { tags: ['@incidents'] }, () => {
before(() => {
cy.beforeBlockCOO(MCP, MP, { dashboards: false, troubleshootingPanel: false });
incidentsPage.warmUpForPlugin();
});

it('5.1 No excessive padding between chart top and alert bars for 100, 200, and 500 alerts', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: "Silenced and Firing Mixed Severity"
description: "One silenced critical incident (resolved) and one firing warning incident."
incidents:
- id: "silenced-critical-resolved-001"
component: "monitoring"
layer: "core"
timeline:
start: "4h"
end: "1h"
alerts:
- name: "SilencedCriticalAlert001"
namespace: "openshift-monitoring"
severity: "critical"
firing: false
silenced: true
timeline:
start: "3h"
end: "2h"

- id: "firing-warning-unsilenced-001"
component: "network"
layer: "core"
timeline:
start: "2h"
alerts:
- name: "FiringWarningAlert001"
namespace: "openshift-network"
severity: "warning"
firing: true
silenced: false
timeline:
start: "1h"
Loading