OBSINTA-1505: improve OLS timeseries Cypress test stability - #1122
Conversation
Target first Perses panel element to avoid ambiguity when multiple panels exist. Replace cy.wait() calls with proper Cypress assertions and timeouts. Improve dashboard creation verification by checking breadcrumb and edit mode buttons instead of page load helper. Signed-off-by: Tomáš Remeš <tremes@redhat.com> Assisted-by: Claude Code:claude-opus-4-6
|
Pipeline controller notification For optional jobs, comment This repository is configured in: LGTM mode |
|
/lgtm |
WalkthroughThe Cypress show-timeseries test now scopes chart checks, validates dashboard creation with breadcrumb and edit-mode assertions, and replaces fixed waits with response-aware Add to Dashboard interactions. ChangesShow-timeseries validation
Estimated code review effort: 2 (Simple) | ~10 minutes Suggested reviewers: 🚥 Pre-merge checks | ✅ 15✅ Passed checks (15 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
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/e2e/coo/03.coo_lightspeed_show_timeseries.cy.ts`:
- Around line 157-165: Update the Add to dashboard interaction in the aiResponse
chain to expand the collapsed tool-call accordion first, then assert the
selected control is visible and enabled before clicking it. Remove force:true
and use a normal click so Cypress validates user actionability.
🪄 Autofix
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: Pro Plus
Run ID: b4cf2f11-5033-4cfa-98b5-948c370ed48d
📒 Files selected for processing (1)
web/cypress/e2e/coo/03.coo_lightspeed_show_timeseries.cy.ts
| // Wait for the "Add to dashboard" button to appear once the streaming response stabilizes. | ||
| // The AI may return multiple show_timeseries tool calls, so pick the first one. | ||
| // The button may be inside a collapsed tool-call accordion in the OLS chat, | ||
| // so use force:true to click it regardless of visibility. | ||
| cy.get(SEL.aiResponse).last().find(SEL.addToDashboard).first().click({ force: true }); | ||
| cy.get(SEL.aiResponse, { timeout: OLS_RESPONSE_TIMEOUT }) | ||
| .last() | ||
| .find(SEL.addToDashboard, { timeout: OLS_RESPONSE_TIMEOUT }) | ||
| .first() | ||
| .click({ force: true }); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -e
printf '%s\n' '--- changed-file summary ---'
git diff --stat
printf '%s\n' '--- target test ---'
cat -n web/cypress/e2e/coo/03.coo_lightspeed_show_timeseries.cy.ts | sed -n '1,210p'
printf '%s\n' '--- selector definitions and related accordion/button usage ---'
rg -n -C 3 "addToDashboard|aiResponse|accordion|Add to dashboard|force: true" web/cypress web --glob '*.{ts,tsx}' | head -n 300Repository: openshift/monitoring-plugin
Length of output: 32089
🌐 Web query:
openshift-lightspeed Add to dashboard aria-label collapsed accordion show_timeseries OLS plugin
💡 Result:
The OpenShift Lightspeed (OLS) plugin for the OpenShift console includes functionality to visualize tool calls, such as the show_timeseries tool, which allows users to render time-series charts directly within the AI chat interface and add them to Perses dashboards [1][2]. Technical implementation details for these UI components include: - ShowTimeseries Component: This component is implemented in the OLS console plugin to handle tool visualization [1]. It uses helper functions and wrappers to manage the integration, including an AddToDashboardButton [1]. - Accessible UI Controls: Development work has specifically addressed accessibility and interaction patterns for these controls [1]. This includes setting descriptive aria-labels (e.g., "Add to dashboard") for action buttons and ensuring that decorative icons (such as ViewGridPlusIcon) are properly hidden from screen readers using aria-hidden={true} [1]. - Dashboard Integration: The "Add to dashboard" feature allows users to take a chart rendered by OLS and persist it into a new or existing Perses dashboard [2]. The integration workflow involves sending a prompt to OLS, receiving the chart, using the UI control to trigger the addition, and verifying the panel's persistence [2]. - Development and Testing: These components are part of the lightspeed-console plugin repository [3][4]. End-to-end tests for the show_timeseries integration are maintained within the plugin's Cypress test suite to ensure the "Add to dashboard" workflow functions correctly across dashboard creation and saving scenarios [2]. Developers working with these components should refer to the web/src/components/ols-tool-ui/ directory within the lightspeed-console project for the source implementation [1].
Citations:
- 1: OU-1264: mcpToolUI basic implementation for OpenShift Lightpseed + obs-mcp + Perses #797
- 2: OBSINTA-1387: add OLS add-to-dashboard e2e test #996
- 3: https://github.com/openshift/lightspeed-console
- 4: https://github.com/openshift/lightspeed-console/
🏁 Script executed:
#!/bin/bash
set -e
python3 - <<'PY'
import json, urllib.request
def get(url):
req = urllib.request.Request(url, headers={"Accept": "application/vnd.github+json", "User-Agent": "review-verifier"})
with urllib.request.urlopen(req, timeout=20) as r:
return json.load(r)
for url in [
"https://api.github.com/repos/openshift/monitoring-plugin/pulls/996/files?per_page=100",
"https://api.github.com/repos/openshift/monitoring-plugin/pulls/797/files?per_page=100",
]:
print(f"--- {url} ---")
try:
data = get(url)
except Exception as e:
print(type(e).__name__, e)
continue
for f in data:
name = f.get("filename", "")
if "lightspeed" in name.lower() or "coo_lightspeed" in name.lower() or "cypress" in name.lower():
print(name, f.get("status"), f.get("additions"), f.get("deletions"))
patch = f.get("patch")
if patch:
print(patch[:12000])
PYRepository: openshift/monitoring-plugin
Length of output: 641
🏁 Script executed:
#!/bin/bash
set -e
python3 - <<'PY'
import json, urllib.request
def get(url):
req = urllib.request.Request(url, headers={"Accept": "application/vnd.github+json", "User-Agent": "review-verifier"})
with urllib.request.urlopen(req, timeout=20) as r:
return json.load(r)
base = "https://api.github.com/repos/openshift/lightspeed-console/contents/web/src/components/ols-tool-ui"
try:
entries = get(base)
for e in entries:
print(e["type"], e["path"])
except Exception as e:
print(type(e).__name__, e)
PYRepository: openshift/monitoring-plugin
Length of output: 309
🏁 Script executed:
#!/bin/bash
set -e
python3 - <<'PY'
import json, urllib.request
def get(url):
req = urllib.request.Request(url, headers={"Accept": "application/vnd.github+json", "User-Agent": "review-verifier"})
with urllib.request.urlopen(req, timeout=20) as r:
return json.load(r)
url = "https://api.github.com/repos/openshift/lightspeed-console/git/trees/main?recursive=1"
try:
data = get(url)
for item in data.get("tree", []):
path = item.get("path", "")
if any(x in path.lower() for x in ("showtimeseries", "ols-tool-ui", "tool-ui", "toolcall", "accordion")):
print(path)
except Exception as e:
print(type(e).__name__, e)
PYRepository: openshift/monitoring-plugin
Length of output: 309
🏁 Script executed:
#!/bin/bash
set -e
for url in \
'https://api.github.com/repos/openshift/monitoring-plugin/pulls/996/files?per_page=100' \
'https://api.github.com/repos/openshift/monitoring-plugin/pulls/797/files?per_page=100' \
'https://api.github.com/repos/openshift/lightspeed-console/git/trees/main?recursive=1'
do
echo "--- $url ---"
curl -ksS -H 'Accept: application/vnd.github+json' -A review-verifier "$url" |
python3 -c '
import json,sys
x=json.load(sys.stdin)
if isinstance(x,list):
for f in x:
n=f.get("filename","")
if any(s in n.lower() for s in ("lightspeed","coo_lightspeed","cypress")):
print(n, f.get("status"), f.get("additions"), f.get("deletions"))
if f.get("patch"): print(f["patch"][:12000])
elif isinstance(x,dict):
for i in x.get("tree",[]):
p=i.get("path","")
if any(s in p.lower() for s in ("showtimeseries","ols-tool-ui","tool-ui","toolcall","accordion")):
print(p)
'
doneRepository: openshift/monitoring-plugin
Length of output: 446
🌐 Web query:
site:github.com/openshift/lightspeed-console "AddToDashboardButton" "show_timeseries"
💡 Result:
There is no evidence in the provided search results to support the existence of a component or function named AddToDashboardButton with a show_timeseries parameter within the OpenShift Lightspeed Console project. The available documentation for the OpenShift Lightspeed Console plugin focuses on its integration as an AI assistant, managing conversation state, and extension patterns for opening the OLS UI [1][2][3][4]. There is no mention of dashboard-specific buttons or time-series display functionality associated with that specific naming convention in the retrieved source materials [1][5][2][6][3][7][4].
Citations:
- 1: https://github.com/openshift/lightspeed-console
- 2: https://github.com/openshift/lightspeed-console/blob/main/AGENTS.md
- 3: Draft: Add conversation persistence and history drawer lightspeed-console#1587
- 4: https://github.com/openshift/lightspeed-console/
- 5: https://github.com/openshift/lightspeed-console/tree/d3694be81e9fbab72689ac04f228aa05aee9b6ce
- 6: PF5: Tests: Fix goToPodDetails helper flakiness lightspeed-console#2082
- 7: https://github.com/openshift/lightspeed-console/blob/d3694be81e9fbab72689ac04f228aa05aee9b6ce/README.md
🏁 Script executed:
#!/bin/bash
set -e
url='https://api.github.com/repos/openshift/lightspeed-console/git/trees/main?recursive=1'
curl -ksS -H 'Accept: application/vnd.github+json' -A review-verifier "$url" |
python3 -c '
import json,sys
x=json.load(sys.stdin)
for i in x.get("tree",[]):
p=i.get("path","")
if any(s in p.lower() for s in ("showtimeseries","ols-tool-ui","tool-ui","toolcall","accordion")):
print(p)
'Repository: openshift/monitoring-plugin
Length of output: 165
🏁 Script executed:
#!/bin/bash
set -e
for url in \
'https://github.com/openshift/monitoring-plugin/pull/996.diff' \
'https://github.com/openshift/monitoring-plugin/pull/797.diff'
do
echo "--- $url ---"
curl -ksSL "$url" | rg -n -C 4 \
'03\.coo_lightspeed_show_timeseries|Add to dashboard|force: true|accordion|aiResponse' \
| head -n 250 || true
doneRepository: openshift/monitoring-plugin
Length of output: 4083
🌐 Web query:
Cypress click force true bypasses actionability checks hidden disabled covered documentation
💡 Result:
In Cypress, passing { force: true } to an action command like.click acts as an "escape hatch" that bypasses Cypress's built-in actionability checks [1][2]. By default, Cypress performs several checks before an action to ensure the element can be interacted with as a real user would; using { force: true } tells Cypress to skip these checks and fire the event regardless of the element's state [1][3][4]. When you use { force: true }, Cypress will NOT perform the following checks [1][2]: - Ensure the element is visible [1][2] - Ensure the element is not covered by another element [1][2] - Ensure the element is not disabled [1][2] - Ensure the element is not animating [1][2] - Ensure the element is not detached from the DOM [1][2] - Ensure the element is not read-only [1][2] - Scroll the element into view [1][2] - Fire the event at a descendant [1][2] While this allows you to trigger events on elements that would otherwise fail these checks, it is generally discouraged because it can mask underlying issues where an element is truly inaccessible to a user (e.g., a button that is hidden or disabled) [3][5][4]. One notable exception is that passing { force: true } to the.select command does not override actionability checks for selecting a disabled or an option within a disabled element [1][2]. Citations: 1: https://docs.cypress.io/app/core-concepts/interacting-with-elements 2: https://docs.cypress.io/llm/markdown/app/core-concepts/interacting-with-elements.md 3: https://www.capocaccia.dev/posts/quickSnippetsForce 4: https://docs.cypress.io/app/references/error-messages 5: https://github.com/cypress-io/eslint-plugin-cypress/blob/HEAD/docs/rules/no-force.md Expand the tool-call accordion before clicking “Add to dashboard”. After the accordion is expanded, assert be.visible and be.enabled, then use .click() without { force: true }. Forced clicks bypass Cypress actionability checks and can pass without proving that a user can use the control. 🤖 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/coo/03.coo_lightspeed_show_timeseries.cy.ts` around lines 157 - 165, Update the Add to dashboard interaction in the aiResponse chain to expand the collapsed tool-call accordion first, then assert the selected control is visible and enabled before clicking it. Remove force:true and use a normal click so Cypress validates user actionability.
|
Scheduling required tests: |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: jgbernalp, tremes The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
|
/label qe-approved |
|
@tremes: This pull request references OBSINTA-1505 which is a valid jira issue. Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "5.0.0" version, but no target version was set. DetailsIn 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. |
|
/test e2e-management-api |
|
@etmurasaki: The specified target(s) for The following commands are available to trigger optional jobs: Use DetailsIn 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 kubernetes-sigs/prow repository. |
|
/override ci/prow/e2e-management-api |
|
@etmurasaki: Overrode contexts on behalf of etmurasaki: ci/prow/e2e-management-api DetailsIn 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 kubernetes-sigs/prow repository. |
|
@tremes: all tests passed! Full PR test history. Your PR dashboard. DetailsInstructions 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. |
Target first Perses panel element to avoid ambiguity when multiple panels exist. Replace cy.wait() calls with proper Cypress assertions and timeouts. Improve dashboard creation verification by checking breadcrumb and edit mode buttons instead of page load helper.
Assisted-by: Claude Code:claude-opus-4-6
Summary by CodeRabbit