Skip to content

NO-JIRA: perses and monitoring automation testing - stabilization#924

Draft
etmurasaki wants to merge 6 commits into
openshift:mainfrom
etmurasaki:etmura-main-fix
Draft

NO-JIRA: perses and monitoring automation testing - stabilization#924
etmurasaki wants to merge 6 commits into
openshift:mainfrom
etmurasaki:etmura-main-fix

Conversation

@etmurasaki
Copy link
Copy Markdown
Contributor

@etmurasaki etmurasaki commented May 11, 2026

Summary by CodeRabbit

  • Tests

    • Enhanced test stability across Perses dashboard, metrics, and monitoring test suites by adding strategic waits and replacing hardcoded delays with visibility assertions.
    • Improved dashboard test setup with proactive cleanup steps to prevent state conflicts.
  • Dependencies

    • Updated Cypress from version 14.2.1 to 15.15.0.
  • Bug Fixes

    • Corrected validation error messages for dashboard operations to align with actual backend responses.

@openshift-ci-robot
Copy link
Copy Markdown

@etmurasaki: This pull request explicitly references no jira issue.

Details

In response to this:

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label May 11, 2026
@openshift-ci openshift-ci Bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label May 11, 2026
@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented May 11, 2026

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented May 11, 2026

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: etmurasaki

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label May 11, 2026
@etmurasaki
Copy link
Copy Markdown
Contributor Author

/test e2e-monitoring

@etmurasaki
Copy link
Copy Markdown
Contributor Author

/test e2e-perses

@etmurasaki
Copy link
Copy Markdown
Contributor Author

/test all

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 11, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

This PR stabilizes Cypress e2e tests for Perses dashboards and monitoring by adding proactive cleanup, replacing fixed waits with conditional polling, quoting shell command arguments, and updating test fixtures and validation messages to match UI changes.

Changes

Perses E2E Test Setup and Fixtures

Layer / File(s) Summary
Perses E2E test setup: cleanup and namespace switching
web/cypress/e2e/perses/00.coo_bvt_perses_admin.cy.ts, web/cypress/e2e/perses/04.coo_import_perses_admin.cy.ts, web/cypress/e2e/perses/99.coo_rbac_perses_user*.cy.ts
Perses e2e test files add cy.cleanupPersesTestDashboardsBeforeTests() in before() hooks and cy.changeNamespace('All Projects') in beforeEach() hooks, along with fixed cy.wait(2000) delays before navigation to ensure consistent namespace context.
Perses dashboard fixture and constant updates
web/cypress/fixtures/coo/coo140_perses/import/testing-perses-dashboard.json, web/cypress/fixtures/coo/coo140_perses/import/testing-perses-dashboard.yaml, web/cypress/fixtures/perses/constants.ts
Dashboard fixture JSON and YAML remove StatusHistoryChart panel and reposition Table panel to span full row width. Test constants are updated to reflect new validation error message strings and dialog selectors.
Perses page objects and test logic updates
web/cypress/support/perses/01.coo_list_perses_admin.cy.ts, web/cypress/support/perses/04.coo_import_perses_admin.cy.ts, web/cypress/support/perses/99.coo_rbac_perses_user1.cy.ts, web/cypress/views/perses-dashboards-create-dashboard.ts, web/cypress/views/perses-dashboards-list-dashboards.ts, web/cypress/views/perses-dashboards-panel.ts, web/cypress/views/perses-dashboards-edit-variables.ts, web/cypress/views/perses-dashboards.ts
Perses page object methods update DOM selectors for validation messages, add extra checkbox interactions for list variables, fix panel modal button locators by removing intermediate h2 traversal, and add fixed waits before assertion completion. Perses list admin and RBAC tests add explicit waits and filter logic.

Cypress Test Framework Improvements

Layer / File(s) Summary
Utility command refactoring: wait stabilization
web/cypress/support/commands/utility-commands.ts
changeNamespace, podImage, and assertNamespace commands are refactored to remove fixed cy.wait(2000) delays and replace them with cy.waitUntil conditions that poll for dropdown visibility or table row presence, plus assertions that verify namespace/filter state post-interaction.
Kubeconfig path quoting in shell commands
web/cypress/support/commands/auth-commands.ts, web/cypress/support/commands/coo-install-commands.ts, web/cypress/support/commands/dashboards-commands.ts, web/cypress/support/commands/operator-commands.ts, web/cypress/support/commands/traces-logging-commands.ts, web/cypress/support/commands/virtualization-commands.ts
Shell command templates across auth, COO install, operator, dashboard, traces, logging, and virtualization command files are updated to wrap KUBECONFIG_PATH in quotes when interpolating into oc and operator-sdk commands, ensuring proper shell argument parsing.
Page object and common view updates
web/cypress/views/common.ts, web/cypress/views/alerting-rule-list-page.ts, web/cypress/views/metrics.ts
Common page object titleShouldHaveText is refactored to use waitUntil with manual h1 element scanning. Alerting rule list page adds byName filter helper. Metrics page object helpers add scrollIntoView before visibility assertions and clicks across units, actions, graph timespan, kebab dropdown, and series toggle interactions.
Monitoring test updates
web/cypress/support/monitoring/00.bvt_monitoring.cy.ts, web/cypress/support/monitoring/03.reg_legacy_dashboards.cy.ts, web/cypress/support/monitoring/06.reg_legacy_dashboards_namespace.cy.ts, web/cypress/support/monitoring/02.reg_metrics_1.cy.ts, web/cypress/support/monitoring/02.reg_metrics_2.cy.ts, web/cypress/support/monitoring/05.reg_metrics_namespace_2.cy.ts, web/cypress/views/silence-alert-page.ts
Monitoring BVT test updates alerting rule filter call. Regression tests remove unnecessary alerts close calls, remove legacy tour setup, add delete-all-queries steps, and add scrollIntoView before graph visibility assertions. Silence alert test updates expected error message text.
Configuration and version updates
web/src/components/data-test.ts, web/package.json
Data test IDs constant updated for Perses dashboard count, and Cypress dev dependency version bumped from 14.2.1 to 15.15.0.

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 11 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (11 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: stabilization of perses and monitoring automation testing through various test setup adjustments, fixture updates, and command refactoring.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Stable And Deterministic Test Names ✅ Passed PR contains no Ginkgo tests; it is a Cypress E2E automation PR with TypeScript/JSON/YAML files only. Custom check does not apply.
Test Structure And Quality ✅ Passed PR contains no Ginkgo tests; it exclusively modifies Cypress E2E tests (TypeScript). Custom check for Ginkgo code quality is not applicable.
Microshift Test Compatibility ✅ Passed No new Ginkgo e2e tests are added in this PR. All changes are to Cypress browser automation tests (TypeScript), not Go-based Ginkgo tests. The MicroShift compatibility check does not apply.
Single Node Openshift (Sno) Test Compatibility ✅ Passed PR contains only Cypress web UI tests and TypeScript support files. No Go-based Ginkgo e2e tests are present, so SNO compatibility check does not apply.
Topology-Aware Scheduling Compatibility ✅ Passed PR modifies only test automation (Cypress tests, fixtures, page objects) and packages, not deployment manifests, operator code, or controllers. No scheduling constraints introduced.
Ote Binary Stdout Contract ✅ Passed OTE Binary Stdout Contract check does not apply to this PR, which contains only TypeScript/JavaScript Cypress test code with no Go binaries or process-level implementations.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed No Ginkgo e2e tests (Go-based) are present in this PR. Changes are limited to Cypress/TypeScript e2e test stabilization and fixtures, which are outside the scope of this check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (8)
web/cypress/support/commands/dashboards-commands.ts (1)

33-66: ⚡ Quick win

Centralize the Perses fixture list instead of hardcoding each manifest here.

The same five filenames are duplicated in setupDashboardsAndPlugins() and cleanupDashboards(), and cleanupDashboards() still has two identical delete branches. Moving these fixture names into one shared array/helper will keep setup and cleanup from drifting and reduce future flake from leftover resources.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/cypress/support/commands/dashboards-commands.ts` around lines 33 - 66, In
setupDashboardsAndPlugins() and cleanupDashboards(), remove the repeated
hardcoded manifest strings and duplicate delete branches by extracting the five
dashboard filenames (openshift-cluster-sample-dashboard.yaml,
perses-dashboard-sample.yaml, prometheus-overview-variables.yaml,
thanos-compact-overview-1var.yaml, thanos-querier-datasource.yaml) into a single
shared array or helper (e.g., DASHBOARD_FIXTURES) and iterate over that array:
in setup call cy.exec with `oc apply -f ./cypress/fixtures/.../<filename>
--kubeconfig ${Cypress.env('KUBECONFIG_PATH')}` for each entry, and in cleanup
iterate the same array to run `oc delete -f .../<filename> --kubeconfig ...`;
also remove the duplicated delete branch currently present in
cleanupDashboards().
web/cypress/views/alerting-rule-list-page.ts (1)

33-47: ⚡ Quick win

Remove try/catch around Cypress command chains in byName.

This try/catch won't reliably catch Cypress command/assertion failures because commands execute asynchronously via Cypress's queue. Cypress commands intentionally fail tests on errors rather than allowing recovery through catch blocks. Use direct command chaining and let Cypress fail naturally.

♻️ Suggested refactor
     byName: (name: string, ouiaId: string = FilterOUIAIDs.RuleNameFilter) => {
-      cy.log('listPage.filter.byName');
-      try {
-        listPage.filter.selectAttribute('Name');
-        cy.byOUIAID(`${ouiaId}-input`)
-          .find('input')
-          .scrollIntoView()
-          .as('input')
-          .should('be.visible');
-        cy.get('@input', { timeout: 10000 })
-          .scrollIntoView()
-          .type(name + '{enter}');
-        cy.get('@input', { timeout: 10000 }).scrollIntoView().should('have.attr', 'value', name);
-      } catch (error) {
-        cy.log(`${error.message}`);
-        throw error;
-      }
+      cy.log('alertingRuleListPage.filter.byName');
+      listPage.filter.selectAttribute('Name');
+      cy.byOUIAID(`${ouiaId}-input`)
+        .find('input')
+        .should('be.visible')
+        .as('input');
+      cy.get('@input', { timeout: 10000 }).clear().type(`${name}{enter}`);
+      cy.get('@input', { timeout: 10000 }).should('have.value', name);
     },
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/cypress/views/alerting-rule-list-page.ts` around lines 33 - 47, Remove
the try/catch wrapper around the Cypress command chain in the byName
implementation: delete the try { ... } catch (error) { ... } block and keep the
direct command chain starting with listPage.filter.selectAttribute('Name')
followed by
cy.byOUIAID(`${ouiaId}-input`).find('input').scrollIntoView().as('input').should('be.visible');
cy.get('@input', { timeout: 10000 }).scrollIntoView().type(name + '{enter}');
cy.get('@input', { timeout: 10000 }).scrollIntoView().should('have.attr',
'value', name); so that Cypress can handle failures natively instead of
attempting to catch them.
web/cypress/views/perses-dashboards-create-dashboard.ts (1)

69-83: ⚡ Quick win

Avoid strict full-text equality for backend error alerts.

Using have.text here is fragile for server-originated messages. Prefer contain.text (or stable fragments) to keep tests robust across minor wording/formatting changes.

♻️ Suggested change
   assertMaxLengthValidation: () => {
     cy.log('persesCreateDashboardsPage.assertMaxLengthValidation');
     cy.byPFRole('dialog')
       .find('h4')
-      .should('have.text', persesCreateDashboard.DIALOG_MAX_LENGTH_VALIDATION)
+      .should('contain.text', 'cannot contain more than 75 characters')
       .should('be.visible');
   },

   assertDuplicatedNameValidation: () => {
     cy.log('persesCreateDashboardsPage.assertDuplicatedNameValidation');
     cy.byPFRole('dialog')
       .find('h4')
-      .should('have.text', persesCreateDashboard.DIALOG_CREATE_NAME_BKD_VALIDATION)
+      .should('contain.text', persesCreateDashboard.DIALOG_CREATE_NAME_BKD_VALIDATION)
       .should('be.visible');
   },
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/cypress/views/perses-dashboards-create-dashboard.ts` around lines 69 -
83, The two assertions in persesCreateDashboardsPage (assertMaxLengthValidation
and assertDuplicatedNameValidation) use strict full-text checks via
should('have.text', ...) which is brittle for backend-originated alerts; change
both to use a containment check (e.g., should('contain.text', ...)) or assert on
a stable fragment of the expected message so the tests tolerate minor
wording/formatting changes while still verifying the correct validation dialog
is shown.
web/cypress/views/perses-dashboards.ts (1)

170-174: ⚡ Quick win

Replace fixed sleep with a deterministic readiness check.

Line 173 adds a hard wait that can still flake under slow CI and always adds delay under fast CI. Prefer asserting a stable post-navigation signal instead of sleeping.

♻️ Suggested change
   cy.byTestID(DataTestIDs.PersesDashboardDropdown)
     .find('input')
     .should('have.value', dashboardName);
-  cy.wait(2000);
+  cy.byAriaLabel(persesAriaLabels.RefreshButton)
+    .scrollIntoView()
+    .should('be.visible');
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/cypress/views/perses-dashboards.ts` around lines 170 - 174, The fixed
cy.wait(2000) should be replaced with a deterministic readiness check: remove
cy.wait and instead assert a stable post-navigation signal such as verifying the
dashboard UI has fully loaded (for example, assert the dashboard title or header
contains dashboardName, or wait on a network alias via cy.intercept and
cy.wait('@alias') that represents fetching the dashboard). Locate the snippet
using DataTestIDs.PersesDashboardDropdown and the input assertion, then replace
the static wait with a targeted assertion like checking the visible dashboard
header/text equals dashboardName or waiting on an XHR/fetch alias that finishes
loading the dashboard content.
web/cypress/support/perses/01.coo_list_perses_admin.cy.ts (1)

369-371: ⚡ Quick win

Use page-ready sync instead of an extra fixed delay.

Line 370 adds another hard wait in the duplicate flow. Replace it with a deterministic list-page load assertion to reduce flakiness and runtime.

♻️ Suggested change
       persesDashboardsPage.backToListPersesDashboardsPage();
-      cy.wait(2000);
+      listPersesDashboardsPage.shouldBeLoaded();
       listPersesDashboardsPage.filter.byProject('perses-dev');
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/cypress/support/perses/01.coo_list_perses_admin.cy.ts` around lines 369 -
371, Replace the fixed cy.wait(2000) after
persesDashboardsPage.backToListPersesDashboardsPage() with a deterministic "page
ready" assertion: remove the hard delay and instead wait for the list page to be
fully loaded by asserting a stable UI signal (for example, a visible table or
filter input, or an existing page-ready helper like
listPersesDashboardsPage.waitForReady()/ensureLoaded()); then call
listPersesDashboardsPage.filter.byProject('perses-dev') once that assertion
passes to avoid flakiness.
web/cypress/e2e/perses/99.coo_rbac_perses_user6.cy.ts (1)

71-73: ⚡ Quick win

Use nav-state assertion instead of fixed delay in beforeEach.

At Line 72, cy.wait(2000) is brittle and slows every test. Wait for the target sidebar item to be visible before clicking it.

♻️ Suggested adjustment
     beforeEach(() => {
       nav.sidenav.clickNavLink(['Observe', 'Dashboards']);
-      cy.wait(2000);
+      cy.get('#page-sidebar').contains('Dashboards (Perses)').should('be.visible');
       nav.sidenav.clickNavLink(['Observe', 'Dashboards (Perses)']);
     });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/cypress/e2e/perses/99.coo_rbac_perses_user6.cy.ts` around lines 71 - 73,
Replace the brittle fixed delay by waiting for the sidebar item to be
present/visible before clicking: remove cy.wait(2000) in the beforeEach and
instead assert the nav state for the target item (use the nav.sidenav API such
as checking the specific nav item or a visibility/state assertion for
['Observe','Dashboards'] or ['Observe','Dashboards (Perses)']) then call
nav.sidenav.clickNavLink([...]) once the assertion passes; update the beforeEach
that currently calls nav.sidenav.clickNavLink(['Observe','Dashboards']);
cy.wait(2000); nav.sidenav.clickNavLink(['Observe','Dashboards (Perses)']) to
assert visibility/state on the sidebar entry and then perform the clicks without
any fixed wait.
web/cypress/support/perses/99.coo_rbac_perses_user1.cy.ts (1)

445-453: ⚡ Quick win

Replace fixed sleep with state-based synchronization in kebab flow.

On Line 445, cy.wait(2000) can still race on slow environments and adds idle delay on fast ones. Prefer waiting on dashboard list state before opening the kebab menu.

♻️ Suggested adjustment
     cy.log(`6.4. Change namespace to openshift-cluster-observability-operator`);
     cy.changeNamespace('openshift-cluster-observability-operator');
-    cy.wait(2000);

     cy.log(`6.5. Assert Kebab icon is enabled`);
     listPersesDashboardsPage.clearAllFilters();
     listPersesDashboardsPage.filter.byProject('openshift-cluster-observability-operator');
     listPersesDashboardsPage.filter.byName(
       persesDashboardsDashboardDropdownCOO.K8S_COMPUTE_RESOURCES_CLUSTER[0],
     );
+    listPersesDashboardsPage.countDashboards('1');
     listPersesDashboardsPage.clickKebabIcon();
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/cypress/support/perses/99.coo_rbac_perses_user1.cy.ts` around lines 445 -
453, Replace the fixed cy.wait(2000) with a state-based wait that ensures the
target dashboard row is present and ready before opening the kebab: after
calling listPersesDashboardsPage.filter.byName(...) wait for the specific
dashboard entry to exist/be visible (e.g., use the page object's selector for
the dashboard row or a new helper like
listPersesDashboardsPage.waitForDashboard(name) that uses
cy.get(...).should('be.visible') or cy.contains(...).should('exist')) and only
then call listPersesDashboardsPage.clickKebabIcon(); this removes the arbitrary
sleep and synchronizes the kebab flow to the actual DOM state.
web/cypress/e2e/perses/99.coo_rbac_perses_user4.cy.ts (1)

72-74: ⚡ Quick win

Replace fixed sleep with a readiness assertion for the Dashboards page heading.

Line 72 adds a hardcoded delay, which can flake under slower conditions and always adds runtime cost. Prefer waiting for the page to be ready by checking for the h1 heading. Use the same pattern already established in the codebase:

Proposed change
       nav.sidenav.clickNavLink(['Observe', 'Dashboards']);
-      cy.wait(2000);
       nav.sidenav.clickNavLink(['Observe', 'Dashboards (Perses)']);
+      cy.contains('h1', 'Dashboards', { timeout: 10000 }).should('be.visible');
       cy.changeNamespace('All Projects');
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/cypress/e2e/perses/99.coo_rbac_perses_user4.cy.ts` around lines 72 - 74,
Remove the hardcoded cy.wait(2000) and instead wait for the Dashboards page to
be ready by asserting the page heading is visible; after
nav.sidenav.clickNavLink(['Observe', 'Dashboards (Perses)']) replace the sleep
with the established readiness check (e.g., assert the h1 heading contains or is
visible for the Dashboards page) so the test waits deterministically before
calling cy.changeNamespace('All Projects').
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@web/cypress/support/commands/dashboards-commands.ts`:
- Around line 34-66: The cy.exec calls that build the oc apply commands
interpolate Cypress.env('KUBECONFIG_PATH') directly which breaks for paths with
spaces or malicious values; update each cy.exec string construction (the oc
apply invocations) to quote the kubeconfig value (e.g. --kubeconfig
"${Cypress.env('KUBECONFIG_PATH')}") or alternatively read const kube =
Cypress.env('KUBECONFIG_PATH') and pass it safely via the cy.exec env option,
ensuring every cy.exec invocation that references Cypress.env('KUBECONFIG_PATH')
is updated.

In `@web/cypress/support/commands/utility-commands.ts`:
- Around line 145-150: After calling cy.changeNamespace(namespace) add a check
that the namespace dropdown or selector has updated to the new namespace value
before asserting row counts so you don't match stale rows; specifically,
immediately after cy.changeNamespace(namespace) validate the namespace control
(the same UI element used for selecting namespaces) reflects the requested
namespace, then proceed to wait for the table rows (e.g., DataViewTable tbody
tr) to ensure the table has reloaded in the new namespace.

In `@web/cypress/views/common.ts`:
- Around line 10-12: The wait callback passed to cy.waitUntil currently contains
an assertion (.should('be.visible')) which throws during retries; change the
callback used in cy.waitUntil to return a boolean by querying the element with
cy.bySemanticElement('h1', title) via Cypress.$(selector) (or get the DOM node
in a .then and use Cypress.dom.isVisible(node)) and return that visibility
boolean, then after cy.waitUntil completes call .scrollIntoView() and assert
.should('be.visible'); keep the existing timeout option.

In `@web/cypress/views/perses-dashboards-edit-variables.ts`:
- Line 132: Replace the brittle positional selector
cy.get('input[type="checkbox"]').eq(2).click() with a stable, scoped selector:
find the modal/container element used in this test (e.g., the edit variables
modal) and target the checkbox by a semantic hook such as a data-testid or by
its associated label text (using cy.contains or aria-label) before calling
.click(); update the test to use that scoped selector (referencing the current
cy.get(...) call and the eq(2) usage) so the intent and checkbox selection
remain stable if DOM order changes.

In `@web/cypress/views/perses-dashboards-list-dashboards.ts`:
- Around line 303-308: The assertion in assertDuplicateDashboardAlreadyExists is
using cy.byPFRole('list') and can match unrelated content; change it to scope to
the active dialog (e.g., target the dialog context with cy.byRole('dialog') or
cy.byPFRole('dialog') and then find the h4). Update the selector in
assertDuplicateDashboardAlreadyExists so the lookup for
persesDashboardsDuplicateDashboard.DIALOG_DUPLICATED_NAME_VALIDATION is
performed inside the dialog (use .within or .find on the dialog element) and
keep the final .contains(...).should('be.visible') assertion.

---

Nitpick comments:
In `@web/cypress/e2e/perses/99.coo_rbac_perses_user4.cy.ts`:
- Around line 72-74: Remove the hardcoded cy.wait(2000) and instead wait for the
Dashboards page to be ready by asserting the page heading is visible; after
nav.sidenav.clickNavLink(['Observe', 'Dashboards (Perses)']) replace the sleep
with the established readiness check (e.g., assert the h1 heading contains or is
visible for the Dashboards page) so the test waits deterministically before
calling cy.changeNamespace('All Projects').

In `@web/cypress/e2e/perses/99.coo_rbac_perses_user6.cy.ts`:
- Around line 71-73: Replace the brittle fixed delay by waiting for the sidebar
item to be present/visible before clicking: remove cy.wait(2000) in the
beforeEach and instead assert the nav state for the target item (use the
nav.sidenav API such as checking the specific nav item or a visibility/state
assertion for ['Observe','Dashboards'] or ['Observe','Dashboards (Perses)'])
then call nav.sidenav.clickNavLink([...]) once the assertion passes; update the
beforeEach that currently calls
nav.sidenav.clickNavLink(['Observe','Dashboards']); cy.wait(2000);
nav.sidenav.clickNavLink(['Observe','Dashboards (Perses)']) to assert
visibility/state on the sidebar entry and then perform the clicks without any
fixed wait.

In `@web/cypress/support/commands/dashboards-commands.ts`:
- Around line 33-66: In setupDashboardsAndPlugins() and cleanupDashboards(),
remove the repeated hardcoded manifest strings and duplicate delete branches by
extracting the five dashboard filenames
(openshift-cluster-sample-dashboard.yaml, perses-dashboard-sample.yaml,
prometheus-overview-variables.yaml, thanos-compact-overview-1var.yaml,
thanos-querier-datasource.yaml) into a single shared array or helper (e.g.,
DASHBOARD_FIXTURES) and iterate over that array: in setup call cy.exec with `oc
apply -f ./cypress/fixtures/.../<filename> --kubeconfig
${Cypress.env('KUBECONFIG_PATH')}` for each entry, and in cleanup iterate the
same array to run `oc delete -f .../<filename> --kubeconfig ...`; also remove
the duplicated delete branch currently present in cleanupDashboards().

In `@web/cypress/support/perses/01.coo_list_perses_admin.cy.ts`:
- Around line 369-371: Replace the fixed cy.wait(2000) after
persesDashboardsPage.backToListPersesDashboardsPage() with a deterministic "page
ready" assertion: remove the hard delay and instead wait for the list page to be
fully loaded by asserting a stable UI signal (for example, a visible table or
filter input, or an existing page-ready helper like
listPersesDashboardsPage.waitForReady()/ensureLoaded()); then call
listPersesDashboardsPage.filter.byProject('perses-dev') once that assertion
passes to avoid flakiness.

In `@web/cypress/support/perses/99.coo_rbac_perses_user1.cy.ts`:
- Around line 445-453: Replace the fixed cy.wait(2000) with a state-based wait
that ensures the target dashboard row is present and ready before opening the
kebab: after calling listPersesDashboardsPage.filter.byName(...) wait for the
specific dashboard entry to exist/be visible (e.g., use the page object's
selector for the dashboard row or a new helper like
listPersesDashboardsPage.waitForDashboard(name) that uses
cy.get(...).should('be.visible') or cy.contains(...).should('exist')) and only
then call listPersesDashboardsPage.clickKebabIcon(); this removes the arbitrary
sleep and synchronizes the kebab flow to the actual DOM state.

In `@web/cypress/views/alerting-rule-list-page.ts`:
- Around line 33-47: Remove the try/catch wrapper around the Cypress command
chain in the byName implementation: delete the try { ... } catch (error) { ... }
block and keep the direct command chain starting with
listPage.filter.selectAttribute('Name') followed by
cy.byOUIAID(`${ouiaId}-input`).find('input').scrollIntoView().as('input').should('be.visible');
cy.get('@input', { timeout: 10000 }).scrollIntoView().type(name + '{enter}');
cy.get('@input', { timeout: 10000 }).scrollIntoView().should('have.attr',
'value', name); so that Cypress can handle failures natively instead of
attempting to catch them.

In `@web/cypress/views/perses-dashboards-create-dashboard.ts`:
- Around line 69-83: The two assertions in persesCreateDashboardsPage
(assertMaxLengthValidation and assertDuplicatedNameValidation) use strict
full-text checks via should('have.text', ...) which is brittle for
backend-originated alerts; change both to use a containment check (e.g.,
should('contain.text', ...)) or assert on a stable fragment of the expected
message so the tests tolerate minor wording/formatting changes while still
verifying the correct validation dialog is shown.

In `@web/cypress/views/perses-dashboards.ts`:
- Around line 170-174: The fixed cy.wait(2000) should be replaced with a
deterministic readiness check: remove cy.wait and instead assert a stable
post-navigation signal such as verifying the dashboard UI has fully loaded (for
example, assert the dashboard title or header contains dashboardName, or wait on
a network alias via cy.intercept and cy.wait('@alias') that represents fetching
the dashboard). Locate the snippet using DataTestIDs.PersesDashboardDropdown and
the input assertion, then replace the static wait with a targeted assertion like
checking the visible dashboard header/text equals dashboardName or waiting on an
XHR/fetch alias that finishes loading the dashboard content.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 6e756565-efc6-4d04-a8f5-cfb4f074cd47

📥 Commits

Reviewing files that changed from the base of the PR and between 3327aad and e7cc169.

📒 Files selected for processing (30)
  • web/cypress/e2e/monitoring/00.bvt_admin.cy.ts
  • web/cypress/e2e/perses/00.coo_bvt_perses_admin.cy.ts
  • web/cypress/e2e/perses/04.coo_import_perses_admin.cy.ts
  • web/cypress/e2e/perses/99.coo_rbac_perses_user1.cy.ts
  • web/cypress/e2e/perses/99.coo_rbac_perses_user2.cy.ts
  • web/cypress/e2e/perses/99.coo_rbac_perses_user3.cy.ts
  • web/cypress/e2e/perses/99.coo_rbac_perses_user4.cy.ts
  • web/cypress/e2e/perses/99.coo_rbac_perses_user5.cy.ts
  • web/cypress/e2e/perses/99.coo_rbac_perses_user6.cy.ts
  • web/cypress/fixtures/coo/coo140_perses/import/testing-perses-dashboard.json
  • web/cypress/fixtures/coo/coo140_perses/import/testing-perses-dashboard.yaml
  • web/cypress/fixtures/perses/constants.ts
  • web/cypress/support/commands/dashboards-commands.ts
  • web/cypress/support/commands/utility-commands.ts
  • web/cypress/support/monitoring/00.bvt_monitoring.cy.ts
  • web/cypress/support/monitoring/03.reg_legacy_dashboards.cy.ts
  • web/cypress/support/monitoring/06.reg_legacy_dashboards_namespace.cy.ts
  • web/cypress/support/perses/01.coo_list_perses_admin.cy.ts
  • web/cypress/support/perses/03.coo_create_perses_admin.cy.ts
  • web/cypress/support/perses/04.coo_import_perses_admin.cy.ts
  • web/cypress/support/perses/99.coo_rbac_perses_user1.cy.ts
  • web/cypress/views/alerting-rule-list-page.ts
  • web/cypress/views/common.ts
  • web/cypress/views/metrics.ts
  • web/cypress/views/perses-dashboards-create-dashboard.ts
  • web/cypress/views/perses-dashboards-edit-variables.ts
  • web/cypress/views/perses-dashboards-list-dashboards.ts
  • web/cypress/views/perses-dashboards-panel.ts
  • web/cypress/views/perses-dashboards.ts
  • web/src/components/data-test.ts
💤 Files with no reviewable changes (4)
  • web/cypress/support/monitoring/03.reg_legacy_dashboards.cy.ts
  • web/cypress/views/perses-dashboards-panel.ts
  • web/cypress/support/monitoring/06.reg_legacy_dashboards_namespace.cy.ts
  • web/cypress/support/perses/04.coo_import_perses_admin.cy.ts

Comment thread web/cypress/support/commands/dashboards-commands.ts
Comment thread web/cypress/support/commands/utility-commands.ts
Comment thread web/cypress/views/common.ts Outdated
if (allowAllValue) {
cy.get('input[name="' + editPersesDashboardsAddVariable.inputAllowAllValue + '"]').click();
if (customAllValue !== undefined && customAllValue !== '') {
cy.get('input[type="checkbox"]').eq(2).click();
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Use a stable, scoped selector instead of positional checkbox indexing.

Line 132 uses cy.get('input[type="checkbox"]').eq(2), which is brittle and can click the wrong checkbox when DOM order changes. Scope to the modal and target by semantic label or test id to avoid reintroducing flakiness.

Suggested change
-        cy.get('input[type="checkbox"]').eq(2).click();
+        cy.byDataTestID(persesMUIDataTestIDs.editDashboardVariablesModal)
+          .contains('label', 'Custom all value')
+          .find('input[type="checkbox"]')
+          .click();
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
cy.get('input[type="checkbox"]').eq(2).click();
cy.byDataTestID(persesMUIDataTestIDs.editDashboardVariablesModal)
.contains('label', 'Custom all value')
.find('input[type="checkbox"]')
.click();
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/cypress/views/perses-dashboards-edit-variables.ts` at line 132, Replace
the brittle positional selector cy.get('input[type="checkbox"]').eq(2).click()
with a stable, scoped selector: find the modal/container element used in this
test (e.g., the edit variables modal) and target the checkbox by a semantic hook
such as a data-testid or by its associated label text (using cy.contains or
aria-label) before calling .click(); update the test to use that scoped selector
(referencing the current cy.get(...) call and the eq(2) usage) so the intent and
checkbox selection remain stable if DOM order changes.

Comment on lines 303 to 308
assertDuplicateDashboardAlreadyExists: () => {
cy.log('listPersesDashboardsPage.assertDuplicateDashboardAlreadyExists');
cy.byPFRole('dialog')
.find(Classes.PersesCreateDashboardDashboardNameError)
cy.byPFRole('list')
.find('h4')
.contains(persesDashboardsDuplicateDashboard.DIALOG_DUPLICATED_NAME_VALIDATION)
.should('be.visible');
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

cd web && find . -name "perses-dashboards-list-dashboards.ts" -type f

Repository: openshift/monitoring-plugin

Length of output: 124


🏁 Script executed:

cd web && wc -l cypress/views/perses-dashboards-list-dashboards.ts

Repository: openshift/monitoring-plugin

Length of output: 126


🏁 Script executed:

cd web && sed -n '290,320p' cypress/views/perses-dashboards-list-dashboards.ts

Repository: openshift/monitoring-plugin

Length of output: 1240


🏁 Script executed:

cd web && rg 'byPFRole.*dialog' -A 3 -B 1 cypress/

Repository: openshift/monitoring-plugin

Length of output: 18885


🏁 Script executed:

cd web && rg 'assertDuplicateDashboardAlreadyExists' -A 10 -B 5 cypress/

Repository: openshift/monitoring-plugin

Length of output: 4819


🏁 Script executed:

cd web && rg 'DIALOG_DUPLICATED_NAME_VALIDATION' -B 2 -A 2 cypress/

Repository: openshift/monitoring-plugin

Length of output: 999


Scope duplicated-name error assertion to the active dialog.

The selector currently uses cy.byPFRole('list'), which is inconsistent with all other dialog validation assertions in this file (e.g., assertMaxLengthValidation, assertRenameDashboardMaxLength) and can match unrelated list content. This method is called immediately after opening a duplicate dialog and should query the dialog context.

🐛 Suggested fix
   assertDuplicateDashboardAlreadyExists: () => {
     cy.log('listPersesDashboardsPage.assertDuplicateDashboardAlreadyExists');
-    cy.byPFRole('list')
+    cy.byPFRole('dialog')
       .find('h4')
       .contains(persesDashboardsDuplicateDashboard.DIALOG_DUPLICATED_NAME_VALIDATION)
       .should('be.visible');
   },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
assertDuplicateDashboardAlreadyExists: () => {
cy.log('listPersesDashboardsPage.assertDuplicateDashboardAlreadyExists');
cy.byPFRole('dialog')
.find(Classes.PersesCreateDashboardDashboardNameError)
cy.byPFRole('list')
.find('h4')
.contains(persesDashboardsDuplicateDashboard.DIALOG_DUPLICATED_NAME_VALIDATION)
.should('be.visible');
assertDuplicateDashboardAlreadyExists: () => {
cy.log('listPersesDashboardsPage.assertDuplicateDashboardAlreadyExists');
cy.byPFRole('dialog')
.find('h4')
.contains(persesDashboardsDuplicateDashboard.DIALOG_DUPLICATED_NAME_VALIDATION)
.should('be.visible');
},
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/cypress/views/perses-dashboards-list-dashboards.ts` around lines 303 -
308, The assertion in assertDuplicateDashboardAlreadyExists is using
cy.byPFRole('list') and can match unrelated content; change it to scope to the
active dialog (e.g., target the dialog context with cy.byRole('dialog') or
cy.byPFRole('dialog') and then find the h4). Update the selector in
assertDuplicateDashboardAlreadyExists so the lookup for
persesDashboardsDuplicateDashboard.DIALOG_DUPLICATED_NAME_VALIDATION is
performed inside the dialog (use .within or .find on the dialog element) and
keep the final .contains(...).should('be.visible') assertion.

@etmurasaki
Copy link
Copy Markdown
Contributor Author

/test e2e-monitoring

1 similar comment
@etmurasaki
Copy link
Copy Markdown
Contributor Author

/test e2e-monitoring

@etmurasaki
Copy link
Copy Markdown
Contributor Author

/test e2e-monitoring

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
web/cypress/e2e/perses/99.coo_rbac_perses_user6.cy.ts (1)

72-72: ⚡ Quick win

Replace fixed sleep with a state-based wait.

Line 72's cy.wait(2000) introduces unnecessary delays and brittle tests sensitive to cluster/UI variance. Cypress best practices strongly recommend deterministic waits instead: chain assertions like .should('be.visible') or .should('exist') to wait for DOM state, use cy.url().should('include', '/expected-path') for navigation verification, or use cy.intercept() with cy.wait('@alias') if waiting for specific network responses. These approaches let tests proceed as soon as conditions are met rather than always consuming the full duration.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/cypress/e2e/perses/99.coo_rbac_perses_user6.cy.ts` at line 72, Replace
the fixed cy.wait(2000) with a deterministic state-based wait: remove the
cy.wait call and instead wait for the UI or network condition that indicates
readiness (for example, assert the target element becomes visible via
cy.get('<selector>').should('be.visible'), assert navigation via
cy.url().should('include', '/expected-path'), or use cy.intercept(...) and
cy.wait('`@alias`') to wait for the backend response); locate the explicit
cy.wait(2000) in the perses test (file 99.coo_rbac_perses_user6.cy.ts) and
replace it with the appropriate .should(...) or cy.wait('`@alias`') that matches
the action immediately following that pause.
web/cypress/e2e/monitoring/00.bvt_admin.cy.ts (1)

18-20: ⚡ Quick win

Replace double-click workaround with explicit route/state assertion.

Lines 18–20 and 41–42 use repeated clicks because the underlying clickNavLink helper relies on a hardcoded cy.wait(2000), which is brittle and insufficient. Rather than doubling clicks to mask the timing issue, refactor the nav helper to gate on actual state readiness: use cy.intercept() to await the navigation request, assert URL changes with cy.location('pathname'), or confirm page-specific elements (e.g., title text) are visible before returning. This eliminates flakiness and aligns with Cypress best practices.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/cypress/e2e/monitoring/00.bvt_admin.cy.ts` around lines 18 - 20, Replace
the double-click workaround by updating the nav helper and tests so navigation
is gated on real readiness: remove the duplicate calls to
nav.sidenav.clickNavLink(['Observe', 'Metrics']) in the test and modify
clickNavLink to wait for the actual navigation to complete (e.g., register a
cy.intercept() for the route, assert cy.location('pathname') changed, or wait
for a page-specific element like the Metrics title to be visible) before
returning; update any calls (e.g., nav.sidenav.clickNavLink) to rely on this
readiness check instead of hardcoded cy.wait(2000).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@web/cypress/views/silence-alert-page.ts`:
- Line 391: The test assertion uses a brittle, fully qualified error string
('Danger alert:invalid silence: matcher set 0: at least one matcher must not
match the empty string'); change the assertion to check only the stable semantic
substring "at least one matcher must not match the empty string" instead (e.g.,
use a contains/should('contain', ...) or string.includes assertion) so the test
anchors on the meaningful message rather than the exact prefix; update the
assertion where that long literal appears to use the shorter substring.

---

Nitpick comments:
In `@web/cypress/e2e/monitoring/00.bvt_admin.cy.ts`:
- Around line 18-20: Replace the double-click workaround by updating the nav
helper and tests so navigation is gated on real readiness: remove the duplicate
calls to nav.sidenav.clickNavLink(['Observe', 'Metrics']) in the test and modify
clickNavLink to wait for the actual navigation to complete (e.g., register a
cy.intercept() for the route, assert cy.location('pathname') changed, or wait
for a page-specific element like the Metrics title to be visible) before
returning; update any calls (e.g., nav.sidenav.clickNavLink) to rely on this
readiness check instead of hardcoded cy.wait(2000).

In `@web/cypress/e2e/perses/99.coo_rbac_perses_user6.cy.ts`:
- Line 72: Replace the fixed cy.wait(2000) with a deterministic state-based
wait: remove the cy.wait call and instead wait for the UI or network condition
that indicates readiness (for example, assert the target element becomes visible
via cy.get('<selector>').should('be.visible'), assert navigation via
cy.url().should('include', '/expected-path'), or use cy.intercept(...) and
cy.wait('`@alias`') to wait for the backend response); locate the explicit
cy.wait(2000) in the perses test (file 99.coo_rbac_perses_user6.cy.ts) and
replace it with the appropriate .should(...) or cy.wait('`@alias`') that matches
the action immediately following that pause.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 565045bb-3dc7-4be2-b428-3264eba166a2

📥 Commits

Reviewing files that changed from the base of the PR and between e7cc169 and 6f2dfa0.

📒 Files selected for processing (31)
  • web/cypress/e2e/monitoring/00.bvt_admin.cy.ts
  • web/cypress/e2e/perses/00.coo_bvt_perses_admin.cy.ts
  • web/cypress/e2e/perses/04.coo_import_perses_admin.cy.ts
  • web/cypress/e2e/perses/99.coo_rbac_perses_user1.cy.ts
  • web/cypress/e2e/perses/99.coo_rbac_perses_user2.cy.ts
  • web/cypress/e2e/perses/99.coo_rbac_perses_user3.cy.ts
  • web/cypress/e2e/perses/99.coo_rbac_perses_user4.cy.ts
  • web/cypress/e2e/perses/99.coo_rbac_perses_user5.cy.ts
  • web/cypress/e2e/perses/99.coo_rbac_perses_user6.cy.ts
  • web/cypress/fixtures/coo/coo140_perses/import/testing-perses-dashboard.json
  • web/cypress/fixtures/coo/coo140_perses/import/testing-perses-dashboard.yaml
  • web/cypress/fixtures/perses/constants.ts
  • web/cypress/support/commands/dashboards-commands.ts
  • web/cypress/support/commands/utility-commands.ts
  • web/cypress/support/monitoring/00.bvt_monitoring.cy.ts
  • web/cypress/support/monitoring/03.reg_legacy_dashboards.cy.ts
  • web/cypress/support/monitoring/06.reg_legacy_dashboards_namespace.cy.ts
  • web/cypress/support/perses/01.coo_list_perses_admin.cy.ts
  • web/cypress/support/perses/03.coo_create_perses_admin.cy.ts
  • web/cypress/support/perses/04.coo_import_perses_admin.cy.ts
  • web/cypress/support/perses/99.coo_rbac_perses_user1.cy.ts
  • web/cypress/views/alerting-rule-list-page.ts
  • web/cypress/views/common.ts
  • web/cypress/views/metrics.ts
  • web/cypress/views/perses-dashboards-create-dashboard.ts
  • web/cypress/views/perses-dashboards-edit-variables.ts
  • web/cypress/views/perses-dashboards-list-dashboards.ts
  • web/cypress/views/perses-dashboards-panel.ts
  • web/cypress/views/perses-dashboards.ts
  • web/cypress/views/silence-alert-page.ts
  • web/src/components/data-test.ts
💤 Files with no reviewable changes (4)
  • web/cypress/views/perses-dashboards-panel.ts
  • web/cypress/support/monitoring/03.reg_legacy_dashboards.cy.ts
  • web/cypress/support/perses/04.coo_import_perses_admin.cy.ts
  • web/cypress/support/monitoring/06.reg_legacy_dashboards_namespace.cy.ts
✅ Files skipped from review due to trivial changes (1)
  • web/cypress/fixtures/coo/coo140_perses/import/testing-perses-dashboard.json
🚧 Files skipped from review as they are similar to previous changes (19)
  • web/cypress/e2e/perses/04.coo_import_perses_admin.cy.ts
  • web/cypress/support/perses/03.coo_create_perses_admin.cy.ts
  • web/cypress/e2e/perses/99.coo_rbac_perses_user3.cy.ts
  • web/cypress/e2e/perses/99.coo_rbac_perses_user2.cy.ts
  • web/cypress/views/perses-dashboards.ts
  • web/cypress/views/perses-dashboards-edit-variables.ts
  • web/cypress/support/monitoring/00.bvt_monitoring.cy.ts
  • web/cypress/views/alerting-rule-list-page.ts
  • web/cypress/support/perses/01.coo_list_perses_admin.cy.ts
  • web/cypress/views/perses-dashboards-list-dashboards.ts
  • web/cypress/views/common.ts
  • web/cypress/e2e/perses/99.coo_rbac_perses_user4.cy.ts
  • web/cypress/e2e/perses/00.coo_bvt_perses_admin.cy.ts
  • web/cypress/views/perses-dashboards-create-dashboard.ts
  • web/cypress/fixtures/perses/constants.ts
  • web/src/components/data-test.ts
  • web/cypress/fixtures/coo/coo140_perses/import/testing-perses-dashboard.yaml
  • web/cypress/support/commands/utility-commands.ts
  • web/cypress/support/perses/99.coo_rbac_perses_user1.cy.ts

Comment thread web/cypress/views/silence-alert-page.ts Outdated
@etmurasaki
Copy link
Copy Markdown
Contributor Author

/test e2e-monitoring

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@web/cypress/support/commands/coo-install-commands.ts`:
- Around line 112-114: The readiness wait cy.exec calls use the kubeconfig
variable unquoted which breaks when the KUBECONFIG_PATH contains spaces; update
all occurrences that call cy.exec with --kubeconfig ${kubeconfig} (e.g., the
cy.exec lines around the kubeconfig const and other instances at the noted
locations) to wrap the kubeconfig value in quotes (--kubeconfig "${kubeconfig}")
so the shell receives the path as a single argument; ensure you update every
similar cy.exec invocation in this file (including the ones near lines 120-121,
133-134, 143-144, 299-300, 311-312) to use the quoted form.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 02f34f6a-b5e8-4f85-a158-08fe7113dc53

📥 Commits

Reviewing files that changed from the base of the PR and between 6f2dfa0 and da77499.

📒 Files selected for processing (13)
  • web/cypress/support/commands/auth-commands.ts
  • web/cypress/support/commands/coo-install-commands.ts
  • web/cypress/support/commands/dashboards-commands.ts
  • web/cypress/support/commands/operator-commands.ts
  • web/cypress/support/commands/traces-logging-commands.ts
  • web/cypress/support/commands/utility-commands.ts
  • web/cypress/support/commands/virtualization-commands.ts
  • web/cypress/support/monitoring/02.reg_metrics_1.cy.ts
  • web/cypress/support/monitoring/02.reg_metrics_2.cy.ts
  • web/cypress/support/monitoring/05.reg_metrics_namespace_2.cy.ts
  • web/cypress/views/common.ts
  • web/cypress/views/metrics.ts
  • web/cypress/views/silence-alert-page.ts
✅ Files skipped from review due to trivial changes (1)
  • web/cypress/support/monitoring/02.reg_metrics_1.cy.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • web/cypress/support/commands/utility-commands.ts

Comment on lines +112 to 114
const kubeconfig = Cypress.env('KUBECONFIG_PATH') as string;

cy.exec(`oc project ${MCP.namespace} --kubeconfig ${kubeconfig}`);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Quote kubeconfig in readiness wait commands as well.

Install/cleanup paths were hardened, but these wait paths still pass --kubeconfig unquoted. If the path contains spaces, waits can fail and make stabilization flaky.

Suggested patch
-    cy.exec(`oc project ${MCP.namespace} --kubeconfig ${kubeconfig}`);
+    cy.exec(`oc project ${MCP.namespace} --kubeconfig "${kubeconfig}"`);

-            `oc get pods -n ${MCP.namespace} -o name --kubeconfig ${kubeconfig} ` +
+            `oc get pods -n ${MCP.namespace} -o name --kubeconfig "${kubeconfig}" ` +
               '| grep observability-operator | grep -v bundle',

-      `oc get pods -n ${MCP.namespace} -o name --kubeconfig ${kubeconfig} ` +
+      `oc get pods -n ${MCP.namespace} -o name --kubeconfig "${kubeconfig}" ` +
         '| grep observability-operator | grep -v bundle',

-            `--timeout=120s --kubeconfig ${kubeconfig}`,
+            `--timeout=120s --kubeconfig "${kubeconfig}"`,

-      cy.exec(`oc get pods -n ${namespace} --kubeconfig ${kubeconfigPath} -o name`, {
+      cy.exec(`oc get pods -n ${namespace} --kubeconfig "${kubeconfigPath}" -o name`, {
         failOnNonZeroExit: false,
       }).then((result) => {

Also applies to: 120-121, 133-134, 143-144, 299-300, 311-312

🧰 Tools
🪛 OpenGrep (1.21.0)

[ERROR] 114-114: Dynamic command passed to child_process.exec/execSync. Use child_process.execFile or spawn with an argument array instead.

(coderabbit.command-injection.exec-js)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/cypress/support/commands/coo-install-commands.ts` around lines 112 - 114,
The readiness wait cy.exec calls use the kubeconfig variable unquoted which
breaks when the KUBECONFIG_PATH contains spaces; update all occurrences that
call cy.exec with --kubeconfig ${kubeconfig} (e.g., the cy.exec lines around the
kubeconfig const and other instances at the noted locations) to wrap the
kubeconfig value in quotes (--kubeconfig "${kubeconfig}") so the shell receives
the path as a single argument; ensure you update every similar cy.exec
invocation in this file (including the ones near lines 120-121, 133-134,
143-144, 299-300, 311-312) to use the quoted form.

@etmurasaki
Copy link
Copy Markdown
Contributor Author

/test e2e-monitoring

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
web/cypress/views/perses-dashboards-create-dashboard.ts (2)

68-69: ⚡ Quick win

Consider using more specific selectors for validation assertions.

The .pf-m-error class is a generic PatternFly modifier that could match multiple error elements if the dialog contains multiple form fields in error states. Consider using a data-test attribute or a selector that targets the specific form field's error message (e.g., scoping to the dashboard name input's form group) to make the test more resilient to UI changes.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/cypress/views/perses-dashboards-create-dashboard.ts` around lines 68 -
69, The assertion currently targets the generic '.pf-m-error' class which can
match multiple errors; scope it to the dashboard name field instead (e.g.,
replace ".find('.pf-m-error')" with a selector that targets the name input's
error such as a data-test/data-testid on the form-group or error span or a
scoped selector like ".form-group:has(input[name=\"dashboardName\"])
.pf-m-error"). Ensure the test still asserts
persesCreateDashboard.DIALOG_MAX_LENGTH_VALIDATION as the expected text and, if
necessary, add a dedicated data-test attribute in the component to make the
selector stable.

75-77: ⚡ Quick win

Scope the list selector to avoid matching unintended elements.

The byPFRole('list') selector is unscoped and could match any list on the page (navigation lists, dropdowns, error alerts, etc.), leading to false positives. If the validation message appears in a specific container (e.g., an alert list within the dialog or a toast notification), scope the selector to that container. Alternatively, consider using a data-test attribute on the validation message element for more precise targeting.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/cypress/views/perses-dashboards-create-dashboard.ts` around lines 75 -
77, The selector cy.byPFRole('list') is unscoped and can match unintended lists;
scope it to the dialog or the specific validation container (e.g., locate the
create-dashboard dialog via cy.byPFRole('dialog') or the dialog root used in
this test, then scope the list lookup inside that container) or add a dedicated
data-test/data-testid on the validation element and assert against that (replace
cy.byPFRole('list').find('h4') with a scoped lookup or
cy.get('[data-testid="..."]') and assert the text equals
persesCreateDashboard.DIALOG_CREATE_NAME_BKD_VALIDATION).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@web/cypress/support/commands/utility-commands.ts`:
- Around line 75-89: The dropdown click is inside the cy.waitUntil retry,
causing toggle race; move the click on Classes.NamespaceDropdown so it runs once
before the cy.waitUntil, and change the waitUntil callback to only query for the
presence of the element with data-test DataTestIDs.NamespaceDropdownTextFilter
(using cy.get('body').then(...) or cy.get(...).its('length') > 0) with the same
{ timeout: 10000, interval: 1000 } so retries only poll for the filter element
and do not re-click the dropdown.

---

Nitpick comments:
In `@web/cypress/views/perses-dashboards-create-dashboard.ts`:
- Around line 68-69: The assertion currently targets the generic '.pf-m-error'
class which can match multiple errors; scope it to the dashboard name field
instead (e.g., replace ".find('.pf-m-error')" with a selector that targets the
name input's error such as a data-test/data-testid on the form-group or error
span or a scoped selector like ".form-group:has(input[name=\"dashboardName\"])
.pf-m-error"). Ensure the test still asserts
persesCreateDashboard.DIALOG_MAX_LENGTH_VALIDATION as the expected text and, if
necessary, add a dedicated data-test attribute in the component to make the
selector stable.
- Around line 75-77: The selector cy.byPFRole('list') is unscoped and can match
unintended lists; scope it to the dialog or the specific validation container
(e.g., locate the create-dashboard dialog via cy.byPFRole('dialog') or the
dialog root used in this test, then scope the list lookup inside that container)
or add a dedicated data-test/data-testid on the validation element and assert
against that (replace cy.byPFRole('list').find('h4') with a scoped lookup or
cy.get('[data-testid="..."]') and assert the text equals
persesCreateDashboard.DIALOG_CREATE_NAME_BKD_VALIDATION).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 9fa516f0-590a-46d9-93df-d01a05e24996

📥 Commits

Reviewing files that changed from the base of the PR and between 6aa45b8 and be72562.

⛔ Files ignored due to path filters (1)
  • web/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (5)
  • web/cypress/fixtures/perses/constants.ts
  • web/cypress/support/commands/utility-commands.ts
  • web/cypress/views/perses-dashboards-create-dashboard.ts
  • web/package.json
  • web/src/components/data-test.ts
✅ Files skipped from review due to trivial changes (2)
  • web/src/components/data-test.ts
  • web/cypress/fixtures/perses/constants.ts

Comment on lines +75 to +89
cy.waitUntil(
() => {
cy.get(Classes.NamespaceDropdown)
.scrollIntoView()
.should('be.visible')
.click({ force: true });
return cy
.get('body')
.then(
($b) =>
$b.find('[data-test="' + DataTestIDs.NamespaceDropdownTextFilter + '"]').length > 0,
);
},
{ timeout: 10000, interval: 1000 },
);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Refactor to prevent dropdown toggle race condition.

The dropdown click is inside the waitUntil retry loop, which means it will be executed on every retry (every 1 second). If the dropdown is already open from a previous iteration, clicking it again will close it, creating a race where the dropdown toggles between open and closed states. This can cause test flakiness.

Move the click outside the retry loop and only use waitUntil to poll for the text filter's appearance.

♻️ Proposed fix
     } else {
-      cy.get(Classes.NamespaceDropdown).scrollIntoView().should('be.visible');
-      cy.waitUntil(
-        () => {
-          cy.get(Classes.NamespaceDropdown)
-            .scrollIntoView()
-            .should('be.visible')
-            .click({ force: true });
-          return cy
-            .get('body')
-            .then(
-              ($b) =>
-                $b.find('[data-test="' + DataTestIDs.NamespaceDropdownTextFilter + '"]').length > 0,
-            );
-        },
-        { timeout: 10000, interval: 1000 },
-      );
+      cy.get(Classes.NamespaceDropdown)
+        .scrollIntoView()
+        .should('be.visible')
+        .click({ force: true });
+      cy.waitUntil(
+        () =>
+          cy
+            .get('body')
+            .then(
+              ($b) =>
+                $b.find('[data-test="' + DataTestIDs.NamespaceDropdownTextFilter + '"]').length > 0,
+            ),
+        { 
+          timeout: 10000, 
+          interval: 500,
+          errorMsg: 'Namespace dropdown text filter did not appear within 10 seconds'
+        },
+      );
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/cypress/support/commands/utility-commands.ts` around lines 75 - 89, The
dropdown click is inside the cy.waitUntil retry, causing toggle race; move the
click on Classes.NamespaceDropdown so it runs once before the cy.waitUntil, and
change the waitUntil callback to only query for the presence of the element with
data-test DataTestIDs.NamespaceDropdownTextFilter (using
cy.get('body').then(...) or cy.get(...).its('length') > 0) with the same {
timeout: 10000, interval: 1000 } so retries only poll for the filter element and
do not re-click the dropdown.

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented May 21, 2026

@etmurasaki: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/e2e-aws-ovn e7cc169 link true /test e2e-aws-ovn
ci/prow/e2e-perses e7cc169 link false /test e2e-perses

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@etmurasaki
Copy link
Copy Markdown
Contributor Author

/test e2e-monitoring

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants