Skip to content

Trt 2782 all tests details links UI#3763

Open
neisw wants to merge 2 commits into
openshift:mainfrom
neisw:trt-2782-all-tests-details-links-ui
Open

Trt 2782 all tests details links UI#3763
neisw wants to merge 2 commits into
openshift:mainfrom
neisw:trt-2782-all-tests-details-links-ui

Conversation

@neisw

@neisw neisw commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

UI implementation of TRT-2782. Relies on #3761

Allows navigation to non regressed test details:
image

Continues to support navigation to regressed tests:
image

Summary by CodeRabbit

  • New Features

    • Component readiness reports now include navigable test-detail links for all analyzed tests, not only regressed tests.
    • Grid cells and test status views can open detailed test reports directly when links are available.
    • Existing regression-focused status and triage behavior remains unchanged.
  • Documentation

    • Added implementation plans covering backend API and frontend navigation updates.
  • Tests

    • Added end-to-end coverage validating links and report data across test statuses.

@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Pipeline controller notification
This repo is configured to use the pipeline controller. Second-stage tests will be triggered either automatically or after lgtm label is added, depending on the repository configuration. The pipeline controller will automatically detect which contexts are required and will utilize /test Prow commands to trigger the second stage.

For optional jobs, comment /test ? to see a list of all defined jobs. To trigger manually all jobs from second stage use /pipeline required command.

This repository is configured in: automatic mode

@openshift-ci openshift-ci Bot requested review from deepsm007 and sosiouxme July 12, 2026 20:54
@openshift-ci

openshift-ci Bot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: neisw

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 Jul 12, 2026
@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

The component readiness API now includes all_tests summaries with test_details links for every test. Frontend cells, toolbar flows, regression panels, and triage views consume these HATEOAS links without forwarding filterVals. Unit and end-to-end tests validate the new behavior.

Changes

All-tests HATEOAS links

Layer / File(s) Summary
Backend all-tests report generation
pkg/api/componentreadiness/..., pkg/apis/api/componentreport/types.go, pkg/api/componentreadiness/middleware/linkinjector/linkinjector.go
Reports collect and expose AllTests, middleware injects links for every status, and regression-only status recomputation remains unchanged.
Frontend cell and utility link handling
sippy-ng/src/component_readiness/CompCapTestRow.js, CompReadyTestCell.js, CompReadyUtils.js, CompReadyUtils.test.js
Level 4 cells prefer all_tests, and link generation uses test-provided HATEOAS URLs with view-specific handling.
Frontend caller and prop plumbing
sippy-ng/src/component_readiness/ComponentReadiness*.js, RegressedTests*.js, Triage*.js, Triaged*.js
Toolbar, modal, panel, and triage call sites remove filterVals forwarding and use the simplified link helper.
API and frontend validation
test/e2e/componentreadiness/alltests_links_test.go, docs/plans/*
Tests verify links, status boundaries, and missing-data behavior; plan documents describe implementation and verification steps.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Suggested labels: ready-for-human-review

Suggested reviewers: xueqzhan

Sequence Diagram(s)

sequenceDiagram
  participant ComponentReport
  participant LinkInjector
  participant FrontendGrid
  ComponentReport->>LinkInjector: process all test comparisons
  LinkInjector-->>ComponentReport: attach test_details links
  ComponentReport-->>FrontendGrid: return all_tests summaries
  FrontendGrid->>FrontendGrid: generate UI link from test HATEOAS data
  FrontendGrid-->>FrontendGrid: render clickable test cell
Loading
🚥 Pre-merge checks | ✅ 19 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Excessive Css In React Should Use Styles ⚠️ Warning CompReadyUtils contains two static inline style objects with 5 props each, and TriagedRegressionTestList has a 4-prop sx block. Move those layout/legend styles to useStyles or styled components; keep only truly dynamic values inline.
✅ Passed checks (19 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and clearly reflects the main change: adding all-tests details links in the UI.
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.
Go Error Handling ✅ Passed PASS: This PR only changes docs and frontend JS; no Go files are modified, so there are no new Go error-handling risks to review.
Sql Injection Prevention ✅ Passed No touched file adds or alters SQL construction; changes are docs/UI/test/report-link logic only, so there’s no new injection surface.
Test Coverage For New Features ✅ Passed Coverage exists: Go report tests assert AllTests, a new e2e test checks test_details links, and CompReadyUtils has unit tests for the new helper.
Single Responsibility And Clear Naming ✅ Passed PASS: The new AllTests/report-link changes are cohesive, and the added helper/type names are specific and narrowly scoped; no generic Manager/Util-style abstractions were introduced.
Feature Documentation ✅ Passed docs/features only contains job-analysis-symptoms.md, unrelated to component readiness; no matching feature doc needed for this PR.
Stable And Deterministic Test Names ✅ Passed Changed test titles are static and descriptive; no It/describe/test names include dynamic values like IDs, timestamps, hosts, or namespaces.
Test Structure And Quality ✅ Passed PASS: The new test is standard Go testing (not Ginkgo), creates no resources, uses a 30s HTTP timeout via SippyGet, and includes clear failure messages.
Microshift Test Compatibility ✅ Passed New test only GETs the Sippy localhost API and checks response links; it uses no OpenShift APIs, namespaces, or MicroShift-unsupported assumptions.
Single Node Openshift (Sno) Test Compatibility ✅ Passed The new test only fetches component-readiness API data and asserts link presence; it has no node/topology/scheduling assumptions or SNO-skipping logic.
Topology-Aware Scheduling Compatibility ✅ Passed No deployment/operator/controller or scheduling-manifest changes were made; the diff is docs/UI/reporting/tests only, with no topology or node-affinity logic.
Ote Binary Stdout Contract ✅ Passed No process-level stdout writes were added; changed Go files lack fmt.Print/klog/log.SetOutput in main/init/suite code, and the new e2e file is just a regular Test body.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed The new e2e test only calls the local Sippy API via an IPv6-safe helper and contains no IPv4 literals or external internet dependencies.
No-Weak-Crypto ✅ Passed No MD5/SHA1/DES/RC4/3DES/Blowfish/ECB or secret-comparison code was added; the only hash is a UI color-bucketing helper, not cryptographic.
Container-Privileges ✅ Passed PR changes only docs and app code; no manifests or privilege flags (privileged, hostPID/Network/IPC, SYS_ADMIN, allowPrivilegeEscalation) were found.
No-Sensitive-Data-In-Logs ✅ Passed No new sensitive-data logs were introduced; touched code mainly removes logging or logs only test IDs/URLs, not secrets or PII.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
sippy-ng/src/component_readiness/TriagedRegressionTestList.js (1)

245-275: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Unguarded href when generateTestDetailsReportLink returns null.

Per the simplification described in the plan doc, generateTestDetailsReportLink now returns null when no HATEOAS link is present. Here, item.url is used directly as href without a null check (<a href={item.url} ...>), unlike CompReadyTestCell.js, which guards with a ternary (link ? <a href={link}>... : ...). If a triaged regression's TestComparison lacks a test_details link, the icon renders inside a non-functional anchor that still looks clickable.

🔧 Proposed guard
-                  <a href={item.url} target="_blank" rel="noopener noreferrer">
-                    <CompSeverityIcon
-                      status={item.status}
-                      explanations={item.explanations}
-                    />
-                  </a>
+                  {item.url ? (
+                    <a href={item.url} target="_blank" rel="noopener noreferrer">
+                      <CompSeverityIcon
+                        status={item.status}
+                        explanations={item.explanations}
+                      />
+                    </a>
+                  ) : (
+                    <CompSeverityIcon
+                      status={item.status}
+                      explanations={item.explanations}
+                    />
+                  )}
🤖 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 `@sippy-ng/src/component_readiness/TriagedRegressionTestList.js` around lines
245 - 275, Update the renderCell logic for the triaged regression status in
TriagedRegressionTestList so a null result from generateTestDetailsReportLink
does not render the icon inside an anchor with an invalid href. Mirror the
guarded link behavior used by CompReadyTestCell.js: render the anchor only when
item.url is present, and render the same icon without a link otherwise.
pkg/api/componentreadiness/component_report.go (1)

125-159: 🚀 Performance & Scalability | 🟡 Minor | ⚡ Quick win

Avoid double post-analysis for regressed tests

AllTests already includes the regressed entries, so those cells run through PostAnalysis twice. Skip the overlap in the second loop or derive one slice from the other to avoid redundant middleware work.

🤖 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 `@pkg/api/componentreadiness/component_report.go` around lines 125 - 159, The
PostAnalysis method currently processes regressed tests twice because AllTests
includes those entries. Update the AllTests loop in
ComponentReportGenerator.PostAnalysis to skip entries already represented in
RegressedTests, or otherwise derive the non-regressed subset, while preserving
post-analysis for tests that are only in AllTests.
sippy-ng/src/component_readiness/RegressedTestsPanel.js (1)

285-313: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Guard against null link from generateTestDetailsReportLink.

generateTestDetailsReportLink can now return null (no HATEOAS link found), but the anchor here is rendered unconditionally. Unlike CompReadyTestCell.js, which conditionally wraps the icon only when a link exists, this will silently render a non-functional <a> with no href.

🐛 Proposed fix to guard the link
-          <a
-            href={generateTestDetailsReportLink(params.row)}
-            target="_blank"
-            rel="noopener noreferrer"
-          >
-            <CompSeverityIcon
-              status={
-                params.row.effective_status
-                  ? params.row.effective_status
-                  : params.row.status
-              }
-              explanations={params.row.explanations}
-            />
-          </a>
+          {(() => {
+            const link = generateTestDetailsReportLink(params.row)
+            const icon = (
+              <CompSeverityIcon
+                status={
+                  params.row.effective_status
+                    ? params.row.effective_status
+                    : params.row.status
+                }
+                explanations={params.row.explanations}
+              />
+            )
+            return link ? (
+              <a href={link} target="_blank" rel="noopener noreferrer">
+                {icon}
+              </a>
+            ) : (
+              icon
+            )
+          })()}
🤖 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 `@sippy-ng/src/component_readiness/RegressedTestsPanel.js` around lines 285 -
313, Update the status column’s renderCell callback to store the result of
generateTestDetailsReportLink(params.row) and render the anchor only when that
link is non-null; otherwise render CompSeverityIcon directly while preserving
its existing status and explanations props.
sippy-ng/src/component_readiness/TriagePotentialMatches.js (1)

352-379: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Guard against null URL in the status cell.

Since generateTestDetailsReportLink can return null when no HATEOAS link exists, testDetailsUrl may be null and the anchor at Line 371 renders with no href, leaving a non-functional link around the icon. Consider conditionally rendering the anchor only when url is truthy, mirroring the pattern in CompReadyTestCell.js.

🐛 Proposed fix to guard the link
       renderCell: (params) => (
         <div className={classes.statusCell}>
-          <a href={params.value.url} target="_blank" rel="noopener noreferrer">
-            <CompSeverityIcon
-              status={params.value.status}
-              explanations={params.value.explanations}
-            />
-          </a>
+          {params.value.url ? (
+            <a href={params.value.url} target="_blank" rel="noopener noreferrer">
+              <CompSeverityIcon
+                status={params.value.status}
+                explanations={params.value.explanations}
+              />
+            </a>
+          ) : (
+            <CompSeverityIcon
+              status={params.value.status}
+              explanations={params.value.explanations}
+            />
+          )}
         </div>
       ),
🤖 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 `@sippy-ng/src/component_readiness/TriagePotentialMatches.js` around lines 352
- 379, Update the status cell’s renderCell logic in TriagePotentialMatches to
render the anchor only when params.value.url is truthy, while always rendering
CompSeverityIcon. Preserve the existing link attributes and icon
status/explanations handling when a URL is available, mirroring the
conditional-link pattern used by CompReadyTestCell.
🧹 Nitpick comments (2)
pkg/api/componentreadiness/component_report_test.go (1)

1220-1227: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Assertion doesn't actually validate "populated" for most cases.

The comment claims this validates that AllTests "is populated," but assert.GreaterOrEqual(len(AllTests), len(RegressedTests)) is trivially true (>= 0) whenever RegressedTests is empty. Most test cases here (e.g. NotSignificant, SignificantImprovement, MissingBasisAndSample statuses) have zero RegressedTests, so the assertion doesn't catch a backend regression where AllTests is left empty for those columns, even though the corresponding e2e test (alltests_links_test.go) expects AllTests to be populated with links for NotSignificant/SignificantImprovement/MissingBasis statuses.

Consider asserting AllTests is non-empty whenever the column status isn't MissingBasisAndSample (i.e., there is real base/sample data), to actually cover the population claim.

♻️ Suggested stronger assertion
 					// AllTests should contain at least as many entries as RegressedTests
 					assert.GreaterOrEqual(t, len(report.Rows[ir].Columns[ic].AllTests),
 						len(report.Rows[ir].Columns[ic].RegressedTests),
 						"AllTests should be a superset of RegressedTests for row %d col %d", ir, ic)
+					// For columns with real base/sample data, AllTests should be populated.
+					if report.Rows[ir].Columns[ic].Status != crtest.MissingBasisAndSample {
+						assert.NotEmpty(t, report.Rows[ir].Columns[ic].AllTests,
+							"AllTests should be populated for row %d col %d with status %d",
+							ir, ic, report.Rows[ir].Columns[ic].Status)
+					}
 					// Clear AllTests for the deep comparison below; the count check above
 					// validates it is populated.
 					report.Rows[ir].Columns[ic].AllTests = nil
🤖 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 `@pkg/api/componentreadiness/component_report_test.go` around lines 1220 -
1227, Strengthen the AllTests validation in the report comparison loop so
columns whose status is not MissingBasisAndSample require a non-empty AllTests
collection, while retaining the existing superset check against RegressedTests.
Keep the exception for MissingBasisAndSample and continue clearing AllTests only
after both validations.
test/e2e/componentreadiness/alltests_links_test.go (1)

26-57: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Both key assertions can be skipped depending on live view data.

The two subtests that actually verify test_details links exist (regressed tests have test_details links in AllTests and non-regressed tests have test_details links in AllTests) both t.Skip if the fetched view happens to lack matching rows. Since the view used is views[0] from whatever the live environment returns, these core assertions may run without ever executing in some environments/CI runs, reducing this e2e test's regression-catching value.

Consider selecting/asserting a view known to contain both regressed and non-regressed test data (or failing loudly if no suitable view is found) rather than silently skipping the primary checks.

Also applies to: 59-86

🤖 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 `@test/e2e/componentreadiness/alltests_links_test.go` around lines 26 - 57, The
link assertions in the subtests “regressed tests have test_details links in
AllTests” and “non-regressed tests have test_details links in AllTests” can be
silently skipped when the selected live view lacks matching rows. Update the
view selection or setup to use a view containing both regressed and
non-regressed data, and fail the test when no suitable view exists instead of
calling t.Skip; keep the existing test_details link assertions unchanged.
🤖 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.

Outside diff comments:
In `@pkg/api/componentreadiness/component_report.go`:
- Around line 125-159: The PostAnalysis method currently processes regressed
tests twice because AllTests includes those entries. Update the AllTests loop in
ComponentReportGenerator.PostAnalysis to skip entries already represented in
RegressedTests, or otherwise derive the non-regressed subset, while preserving
post-analysis for tests that are only in AllTests.

In `@sippy-ng/src/component_readiness/RegressedTestsPanel.js`:
- Around line 285-313: Update the status column’s renderCell callback to store
the result of generateTestDetailsReportLink(params.row) and render the anchor
only when that link is non-null; otherwise render CompSeverityIcon directly
while preserving its existing status and explanations props.

In `@sippy-ng/src/component_readiness/TriagedRegressionTestList.js`:
- Around line 245-275: Update the renderCell logic for the triaged regression
status in TriagedRegressionTestList so a null result from
generateTestDetailsReportLink does not render the icon inside an anchor with an
invalid href. Mirror the guarded link behavior used by CompReadyTestCell.js:
render the anchor only when item.url is present, and render the same icon
without a link otherwise.

In `@sippy-ng/src/component_readiness/TriagePotentialMatches.js`:
- Around line 352-379: Update the status cell’s renderCell logic in
TriagePotentialMatches to render the anchor only when params.value.url is
truthy, while always rendering CompSeverityIcon. Preserve the existing link
attributes and icon status/explanations handling when a URL is available,
mirroring the conditional-link pattern used by CompReadyTestCell.

---

Nitpick comments:
In `@pkg/api/componentreadiness/component_report_test.go`:
- Around line 1220-1227: Strengthen the AllTests validation in the report
comparison loop so columns whose status is not MissingBasisAndSample require a
non-empty AllTests collection, while retaining the existing superset check
against RegressedTests. Keep the exception for MissingBasisAndSample and
continue clearing AllTests only after both validations.

In `@test/e2e/componentreadiness/alltests_links_test.go`:
- Around line 26-57: The link assertions in the subtests “regressed tests have
test_details links in AllTests” and “non-regressed tests have test_details links
in AllTests” can be silently skipped when the selected live view lacks matching
rows. Update the view selection or setup to use a view containing both regressed
and non-regressed data, and fail the test when no suitable view exists instead
of calling t.Skip; keep the existing test_details link assertions unchanged.

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Enterprise

Run ID: 77ccaa38-f04f-47bd-8e1b-f0035fecb88f

📥 Commits

Reviewing files that changed from the base of the PR and between 9370b21 and e6b3762.

📒 Files selected for processing (22)
  • docs/plans/trt-2782-all-tests-links.md
  • docs/plans/trt-2782-frontend-hateoas-links.md
  • pkg/api/componentreadiness/component_report.go
  • pkg/api/componentreadiness/component_report_test.go
  • pkg/api/componentreadiness/middleware/linkinjector/linkinjector.go
  • pkg/apis/api/componentreport/types.go
  • sippy-ng/src/component_readiness/CompCapTestRow.js
  • sippy-ng/src/component_readiness/CompReadyEnvCapabilities.js
  • sippy-ng/src/component_readiness/CompReadyEnvCapability.js
  • sippy-ng/src/component_readiness/CompReadyEnvCapabilityTest.js
  • sippy-ng/src/component_readiness/CompReadyTestCell.js
  • sippy-ng/src/component_readiness/CompReadyUtils.js
  • sippy-ng/src/component_readiness/CompReadyUtils.test.js
  • sippy-ng/src/component_readiness/ComponentReadiness.js
  • sippy-ng/src/component_readiness/ComponentReadinessToolBar.js
  • sippy-ng/src/component_readiness/RegressedTestsModal.js
  • sippy-ng/src/component_readiness/RegressedTestsPanel.js
  • sippy-ng/src/component_readiness/Triage.js
  • sippy-ng/src/component_readiness/TriagePotentialMatches.js
  • sippy-ng/src/component_readiness/TriagedRegressionTestList.js
  • sippy-ng/src/component_readiness/TriagedTestsPanel.js
  • test/e2e/componentreadiness/alltests_links_test.go
💤 Files with no reviewable changes (7)
  • sippy-ng/src/component_readiness/CompReadyEnvCapabilities.js
  • sippy-ng/src/component_readiness/ComponentReadiness.js
  • sippy-ng/src/component_readiness/CompReadyEnvCapability.js
  • sippy-ng/src/component_readiness/TriagedTestsPanel.js
  • sippy-ng/src/component_readiness/Triage.js
  • pkg/api/componentreadiness/middleware/linkinjector/linkinjector.go
  • sippy-ng/src/component_readiness/RegressedTestsModal.js

@openshift-ci openshift-ci Bot added the ready-for-human-review Indicates a PR has been reviewed by automated tools and is ready for human review label Jul 12, 2026
@openshift-ci

openshift-ci Bot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

@neisw: 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/unit e6b3762 link true /test unit
ci/prow/lint e6b3762 link true /test lint
ci/prow/images e6b3762 link true /test images
ci/prow/build e6b3762 link true /test build
ci/prow/security e6b3762 link true /test security

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.

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. ready-for-human-review Indicates a PR has been reviewed by automated tools and is ready for human review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant