Skip to content

Commit 03ddbe2

Browse files
Claude Agentclaude
andcommitted
fix(tests): use bar groups for incident selection, add warm-up to BVT
- selectIncidentByBarIndex/deselectIncidentByBar: use incidentsChartBarsGroups() (one element per incident) instead of incidentsChartBarsVisiblePaths() (flattened paths). Fixes incorrect incident selection/deselection with multi-severity incidents. - findIncidentWithAlert: count bar groups instead of flattened paths - deselectIncidentByBar: accept index parameter to deselect the correct incident instead of always clicking the first bar - 01.incidents.cy.ts: add warmUpForPlugin() to before() hook — same plugin loading race fix as reg/02-05 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 2e6f654 commit 03ddbe2

2 files changed

Lines changed: 31 additions & 30 deletions

File tree

web/cypress/e2e/incidents/01.incidents.cy.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ const MP = {
2727
describe('BVT: Incidents - UI', { tags: ['@smoke', '@incidents'] }, () => {
2828
before(() => {
2929
cy.beforeBlockCOO(MCP, MP, { dashboards: false, troubleshootingPanel: false });
30+
incidentsPage.warmUpForPlugin();
3031
cy.mockIncidentFixture(
3132
'incident-scenarios/1-single-incident-firing-critical-and-warning-alerts.yaml',
3233
);

web/cypress/views/incidents-page.ts

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -399,42 +399,37 @@ export const incidentsPage = {
399399
},
400400

401401
/**
402-
* Selects an incident from the chart by clicking on a bar at the specified index.
403-
* BUG: Problems with multi-severity incidents (multiple paths in a single incident bar)
402+
* Selects an incident from the chart by clicking on a bar group at the
403+
* specified index. Uses bar groups (one per incident) instead of flattened
404+
* paths to correctly handle multi-severity incidents.
404405
*
405406
* @param index - Zero-based index of the incident bar to click (default: 0)
406407
* @returns Promise that resolves when the incidents table is visible
407408
*/
408409
selectIncidentByBarIndex: (index = 0) => {
409-
if (!_quietSearch)
410-
cy.log(`incidentsPage.selectIncidentByBarIndex: ${index} (clicking visible path elements)`);
410+
if (!_quietSearch) cy.log(`incidentsPage.selectIncidentByBarIndex: ${index}`);
411411

412412
return incidentsPage.elements
413-
.incidentsChartBarsVisiblePaths()
413+
.incidentsChartBarsGroups()
414414
.should('have.length.greaterThan', index)
415-
.then(($paths) => {
416-
if (index >= $paths.length) {
417-
throw new Error(`Index ${index} exceeds available paths (${$paths.length})`);
418-
}
419-
420-
return cy.wrap($paths.eq(index), _qLog()).click({ force: true, ..._qLog() });
421-
})
415+
.eq(index)
416+
.find('path[role="presentation"]')
417+
.first()
418+
.click({ force: true, ..._qLog() })
422419
.then(() => {
423420
cy.wait(2000, _qLog());
424421
return incidentsPage.elements.incidentsTable().scrollIntoView().should('exist');
425422
});
426423
},
427424

428-
deselectIncidentByBar: () => {
425+
deselectIncidentByBar: (index = 0) => {
429426
if (!_quietSearch) cy.log('incidentsPage.deselectIncidentByBar');
430427
return incidentsPage.elements
431-
.incidentsChartBarsVisiblePaths()
432-
.then(($paths) => {
433-
if ($paths.length === 0) {
434-
throw new Error('No paths found in incidents chart');
435-
}
436-
return cy.wrap($paths.eq(0), _qLog()).click({ force: true, ..._qLog() });
437-
})
428+
.incidentsChartBarsGroups()
429+
.eq(index)
430+
.find('path[role="presentation"]')
431+
.first()
432+
.click({ force: true, ..._qLog() })
438433
.then(() => {
439434
return incidentsPage.elements.incidentsTable().should('not.exist');
440435
});
@@ -653,8 +648,10 @@ export const incidentsPage = {
653648

654649
prepareIncidentsPageForSearch: () => {
655650
if (!_quietSearch) cy.log('incidentsPage.prepareIncidentsPageForSearch: Setting up page...');
656-
// Force a hard page reload to release browser DOM memory from previous search iterations.
657-
cy.reload({ log: false });
651+
// Use SPA navigation instead of cy.reload() — the Incidents component is a
652+
// dynamic plugin chunk, and cy.reload() causes the Console to re-resolve all
653+
// plugins from scratch, which silently fails in headless CI (blank page).
654+
// OOM is handled by _quietSearch suppressing DOM snapshots, not by reload.
658655
incidentsPage.goTo();
659656
incidentsPage.setDays(incidentsPage.SEARCH_CONFIG.DEFAULT_DAYS);
660657
incidentsPage.elements.incidentsChartContainer().should('be.visible');
@@ -821,7 +818,7 @@ export const incidentsPage = {
821818
if (found) {
822819
return cy.wrap(true, _qLog());
823820
}
824-
incidentsPage.deselectIncidentByBar();
821+
incidentsPage.deselectIncidentByBar(currentIndex);
825822
cy.wait(500, _qLog());
826823
return searchNextIncidentBar(currentIndex + 1);
827824
});
@@ -859,16 +856,19 @@ export const incidentsPage = {
859856

860857
incidentsPage.prepareIncidentsPageForSearch();
861858

862-
return incidentsPage.elements
863-
.incidentsChartBarsVisiblePaths()
864-
.then(($paths) => {
865-
const totalPaths = $paths.length;
866-
if (totalPaths === 0) {
867-
cy.log('No visible incident bar paths found in chart');
859+
// Check for bar groups without asserting existence — an empty chart is
860+
// valid (e.g. when mocking empty incidents or before detection fires).
861+
return cy
862+
.get('body', _qLog())
863+
.then(($body) => {
864+
const barSelector = 'g[role="presentation"][data-test*="incidents-chart-bar-"]';
865+
const totalIncidents = $body.find(barSelector).length;
866+
if (totalIncidents === 0) {
867+
if (!_quietSearch) cy.log('No incident bar groups found in chart');
868868
return cy.wrap(false, { log: false });
869869
}
870870

871-
return incidentsPage.traverseAllIncidentsBars(alertName, totalPaths);
871+
return incidentsPage.traverseAllIncidentsBars(alertName, totalIncidents);
872872
})
873873
.then((found: boolean) => {
874874
if (found) {

0 commit comments

Comments
 (0)