Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 19 additions & 12 deletions web/cypress/e2e/coo/03.coo_lightspeed_show_timeseries.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,15 @@ describe('COO-LightSpeed: show_timeseries', { tags: ['@ols'] }, () => {
.should('exist');

cy.get(SEL.persesPanel, { timeout: OLS_RESPONSE_TIMEOUT })
.should('exist')
.first()
.scrollIntoView()
.should('be.visible');

cy.get(SEL.persesPanel).find(SEL.persesSvg).should('exist');
cy.get(SEL.persesPanel).first().find(SEL.persesSvg).should('exist');

cy.get(SEL.persesPanel).should('contain.text', 'CPU');
cy.get(SEL.persesPanel).should('contain.text', 'openshift-monitoring');
cy.get(SEL.persesPanel).find('svg path[d]').should('have.length.greaterThan', 0);
cy.get(SEL.persesPanel).first().should('contain.text', 'CPU');
cy.get(SEL.persesPanel).first().should('contain.text', 'openshift-monitoring');
cy.get(SEL.persesPanel).first().find('svg path[d]').should('have.length.greaterThan', 0);
});

it('adds the rendered chart to a new Perses dashboard via Add to Dashboard button', () => {
Expand All @@ -121,7 +121,12 @@ describe('COO-LightSpeed: show_timeseries', { tags: ['@ols'] }, () => {
persesCreateDashboardsPage.selectProject(DASHBOARD_PROJECT);
persesCreateDashboardsPage.enterDashboardName(DASHBOARD_NAME);
persesCreateDashboardsPage.createDashboardDialogCreateButton();
persesDashboardsPage.shouldBeLoadedEditionMode(DASHBOARD_NAME);
commonPages.titleShouldHaveText('Dashboards');
cy.byTestID('perses-dashboards-breadcrumb-dashboard-name-item')
.scrollIntoView()
.should('contain', DASHBOARD_NAME)
.should('be.visible');
persesDashboardsPage.assertEditModeButtons();
persesDashboardsPage.shouldBeLoadedEditionModeFromCreateDashboard();

// Save the empty dashboard first so it exits edit mode
Expand Down Expand Up @@ -149,20 +154,22 @@ describe('COO-LightSpeed: show_timeseries', { tags: ['@ols'] }, () => {

cy.get(SEL.persesPanel, { timeout: OLS_RESPONSE_TIMEOUT }).should('exist');

// Wait for the streaming response to stabilize before interacting
cy.wait(5000);

// The "Add to dashboard" button should be visible because a dashboard is open.
// 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 });
Comment on lines +157 to +165

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 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 300

Repository: 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:


🏁 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])
PY

Repository: 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)
PY

Repository: 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)
PY

Repository: 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)
'
done

Repository: 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:


🏁 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
done

Repository: 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.


// Close the chat panel to see the dashboard
cy.get(SEL.chatButton).click();
cy.get(SEL.chatPanel).should('not.exist');

// The dashboard should have entered edit mode and the panel should be added
cy.wait(5000);
persesDashboardsPage.assertEditModeButtons();

// Verify a panel was added to the dashboard
cy.byDataTestID(persesMUIDataTestIDs.panelHeader).find('h6').should('be.visible');
Expand Down