Skip to content

test(e2e): add BDD tests for CVSS display and vulnerability detail tabs#1110

Open
xinredhat wants to merge 1 commit into
guacsec:release/0.5.zfrom
xinredhat:TC-4635
Open

test(e2e): add BDD tests for CVSS display and vulnerability detail tabs#1110
xinredhat wants to merge 1 commit into
guacsec:release/0.5.zfrom
xinredhat:TC-4635

Conversation

@xinredhat

@xinredhat xinredhat commented Jun 29, 2026

Copy link
Copy Markdown

Add 28 E2E BDD tests covering 5 gaps identified in TC-4635:

  • Gap 1: CVSS Score Breakdown popover on SBOM Vulnerabilities tab (8 tests)
  • Gap 2: CVSS score, severity, and version tag on Vulnerability list page (4 tests)
  • Gap 3: CVSS Assessment panel on Vulnerability details page (3 tests)
  • Gap 4: Related SBOMs tab with status, supplier, and dependency expansion (7 tests)
  • Gap 5: Related Advisories tab with multi-type advisory validation (6 tests)

Assisted-by: Claude

Summary by Sourcery

Add end-to-end BDD coverage for CVSS-related UI and vulnerability detail views across SBOM and vulnerability explorer pages.

Tests:

  • Add BDD step definitions and feature files validating CVSS severity, score, and version tags in the vulnerability list and details views.
  • Add tests for the CVSS Score Breakdown popover on SBOM vulnerability tabs, including highest severity, score, and per-source row verification.
  • Add tests for the CVSS Assessment panel presence and content, including source, version, severity, score, vector string, and handling of vulnerabilities without CVSS data.
  • Add tests for the Related SBOMs tab, covering SBOM status/version display, dependency expansion, and links to package detail pages.
  • Add tests for the Related Advisories tab, covering advisory type (CVE/OSV/CSAF), row counts, and filter/search behavior.
  • Introduce test datasets for multi-advisory CVSS scenarios and advisory CVSS score records to support the new E2E coverage.

@sourcery-ai

sourcery-ai Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Adds Playwright BDD end-to-end coverage for CVSS display in the vulnerability and SBOM explorers, plus related SBOMs/advisories tabs, backed by new test datasets for multi-source CVSS scoring.

File-Level Changes

Change Details Files
Introduce BDD steps and scenarios to validate CVSS column behavior on the Vulnerability list (severity, score, version tag, and tooltip).
  • Add cvss-score-version.feature with scenarios for CVSS severity/score/version and Unknown state in the vulnerability list.
  • Add cvss-score-version.step.ts step definitions to filter by vulnerability ID and assert CVSS cell contents and header tooltip text.
e2e/tests/ui/features/@vulnerability-explorer/cvss-score-version.feature
e2e/tests/ui/features/@vulnerability-explorer/cvss-score-version.step.ts
Add page object and BDD coverage for the CVSS Assessment panel on the Vulnerability details page.
  • Create CvssAssessmentPanel page object encapsulating heading, source, version, severity, score, vector, and severity badge assertions.
  • Add cvss-assessment.feature to cover visible/hidden panel states and expected CVSS details for selected vulnerabilities.
  • Add cvss-assessment.step.ts step definitions delegating to the CvssAssessmentPanel methods.
e2e/tests/ui/pages/vulnerability-details/info/CvssAssessmentPanel.ts
e2e/tests/ui/features/@vulnerability-explorer/cvss-assessment.feature
e2e/tests/ui/features/@vulnerability-explorer/cvss-assessment.step.ts
Add page object and BDD tests for the CVSS Score Breakdown popover in the SBOM vulnerabilities tab.
  • Create CvssBreakdownPopover page object to locate the popover dialog, highest-score row, and advisory breakdown table, with helpers for row count and row values.
  • Add cvss-score-breakdown.feature to validate popover visibility, highest severity/score, and number of advisory sources for multi-source vulnerabilities.
  • Add cvss-score-breakdown.step.ts step definitions to open the Sources popover from the SBOM vulnerabilities tab and assert contents via CvssBreakdownPopover.
e2e/tests/ui/pages/sbom-details/vulnerabilities/CvssBreakdownPopover.ts
e2e/tests/ui/features/@sbom-explorer/cvss-score-breakdown.feature
e2e/tests/ui/features/@sbom-explorer/cvss-score-breakdown.step.ts
Add BDD coverage for the Related SBOMs tab, including dependency expansion and package links, on Vulnerability details.
  • Create DependencySubTable page object to represent expanded dependency tables and verify row fields and name links.
  • Add related-sboms.feature scenarios for SBOM status/version, dependency sub-table contents, and navigation links to package details.
  • Add related-sboms.step.ts step definitions to expand SBOM dependencies and assert dependency row data and links via DependencySubTable.
e2e/tests/ui/pages/vulnerability-details/sboms/DependencySubTable.ts
e2e/tests/ui/features/@vulnerability-explorer/related-sboms.feature
e2e/tests/ui/features/@vulnerability-explorer/related-sboms.step.ts
Add BDD coverage for the Related Advisories tab, validating advisory IDs, types, counts, and filtering.
  • Add related-advisories.feature with scenarios for advisory ID/type validation, minimum advisory counts, and filter/search behavior on the tab.
  • Add related-advisories.step.ts step definitions to assert advisory type, row counts, and filtered results using the AdvisoriesTab page object and table helpers.
e2e/tests/ui/features/@vulnerability-explorer/related-advisories.feature
e2e/tests/ui/features/@vulnerability-explorer/related-advisories.step.ts
Introduce dedicated test datasets for CVSS scores and multi-advisory SBOM used across the new E2E BDD tests.
  • Add advisory CVSS score JSON fixtures for CVEs, GHSAs, and RHSAs referenced in the scenarios.
  • Add multi_advisory_cvss_test SBOM JSON fixture used to drive multi-source vulnerability and related SBOMs scenarios.
e2e/tests/common/dataset/advisory/cvssscore/CVE-2020-13936.json
e2e/tests/common/dataset/advisory/cvssscore/CVE-2021-44906.json
e2e/tests/common/dataset/advisory/cvssscore/CVE-2023-28755.json
e2e/tests/common/dataset/advisory/cvssscore/CVE-2025-61594.json
e2e/tests/common/dataset/advisory/cvssscore/GHSA-59j4-wjwp-mw9m.json
e2e/tests/common/dataset/advisory/cvssscore/GHSA-hv5j-3wm6-xx2r.json
e2e/tests/common/dataset/advisory/cvssscore/GHSA-xvch-5gv4-984h.json
e2e/tests/common/dataset/advisory/cvssscore/cve-2020_13936.json
e2e/tests/common/dataset/advisory/cvssscore/rhsa-2022_9073.json
e2e/tests/common/dataset/advisory/cvssscore/rhsa-2024_1576.json
e2e/tests/common/dataset/advisory/cvssscore/rhsa-2025_23062.json
e2e/tests/common/dataset/sbom/multi_advisory_cvss_test.json

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai 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.

Hey - I've found 1 issue, and left some high level feedback:

  • Several helpers (e.g., DependencySubTable.verifyRowByName and CvssAssessmentPanel.verifySeverityBadge) rely on cell indices or global text matching, which makes the tests sensitive to layout/text changes; consider targeting cells via data-labels or scoping locators to their section to reduce brittleness.
  • CvssBreakdownPopover.verifyRowValues filters rows using page-level locators rather than scoping the match to the breakdown table, which could accidentally match other content on the page; it would be more robust to use has locators derived from the table itself.
  • The new feature files hard-code specific vulnerability/advisory IDs and SBOM names, so any dataset updates will break multiple scenarios at once; if possible, centralize these test fixtures or add a helper to look up IDs by semantic description to make future data changes easier to manage.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Several helpers (e.g., DependencySubTable.verifyRowByName and CvssAssessmentPanel.verifySeverityBadge) rely on cell indices or global text matching, which makes the tests sensitive to layout/text changes; consider targeting cells via data-labels or scoping locators to their section to reduce brittleness.
- CvssBreakdownPopover.verifyRowValues filters rows using page-level locators rather than scoping the match to the breakdown table, which could accidentally match other content on the page; it would be more robust to use `has` locators derived from the table itself.
- The new feature files hard-code specific vulnerability/advisory IDs and SBOM names, so any dataset updates will break multiple scenarios at once; if possible, centralize these test fixtures or add a helper to look up IDs by semantic description to make future data changes easier to manage.

## Individual Comments

### Comment 1
<location path="e2e/tests/ui/pages/vulnerability-details/sboms/DependencySubTable.ts" line_range="20-29" />
<code_context>
+    return new DependencySubTable(page, table);
+  }
+
+  async verifyRowByName(
+    depName: string,
+    depType: string,
+    depNamespace: string,
+    depVersion: string,
+  ) {
+    const row = this._table.locator("tbody tr").filter({
+      has: this._page.getByRole("link", { name: depName, exact: true }),
+    });
+    await expect(row).toBeVisible();
+
+    const cells = row.locator("td");
+    await expect(cells.nth(0)).toHaveText(depType);
+    if (depNamespace) {
+      await expect(cells.nth(1)).toHaveText(depNamespace);
+    }
+    await expect(cells.nth(3)).toHaveText(depVersion);
+  }
+
</code_context>
<issue_to_address>
**suggestion:** Add explicit assertions for the namespace cell in `verifyRowByName`, including the empty namespace case

Currently the test only checks `cells.nth(1)` when `depNamespace` is truthy, so rows with an empty or undefined namespace aren’t validated. Please add explicit expectations for both cases: assert the namespace cell text when `depNamespace` is set, and when it’s empty or a sentinel value, assert that the cell is empty or shows the expected "no namespace" indicator. This will ensure the SBOM dependency rendering is fully covered.

Suggested implementation:

```typescript
  async verifyRowByName(
    depName: string,
    depType: string,
    depNamespace: string | null | undefined,
    depVersion: string,
  ) {
    const row = this._table.locator("tbody tr").filter({
      has: this._page.getByRole("link", { name: depName, exact: true }),
    });
    await expect(row).toBeVisible();

    const cells = row.locator("td");
    await expect(cells.nth(0)).toHaveText(depType);

    const namespaceCell = cells.nth(1);
    if (depNamespace) {
      // Explicitly validate the rendered namespace when provided.
      await expect(namespaceCell).toHaveText(depNamespace);
    } else {
      // Explicitly validate the "no namespace" rendering (empty cell / indicator).
      await expect(namespaceCell).toHaveText("");
    }

    await expect(cells.nth(3)).toHaveText(depVersion);
  }

```

If the UI renders a specific "no namespace" indicator (e.g. "—" or "No namespace") instead of an empty string, replace `await expect(namespaceCell).toHaveText("");` with that exact expected text so the assertion matches the SBOM dependency rendering.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@codecov

codecov Bot commented Jun 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 50.68%. Comparing base (00036cb) to head (badef08).

Additional details and impacted files
@@              Coverage Diff               @@
##           release/0.5.z    #1110   +/-   ##
==============================================
  Coverage          50.68%   50.68%           
==============================================
  Files                253      253           
  Lines               5497     5497           
  Branches            1659     1659           
==============================================
  Hits                2786     2786           
  Misses              2441     2441           
  Partials             270      270           
Flag Coverage Δ
unit 2.01% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@xinredhat

Copy link
Copy Markdown
Author

@sourcery-ai review

@sourcery-ai sourcery-ai 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.

Hey - I've found 2 issues, and left some high level feedback:

  • Several selectors rely on visible text (e.g., heading names, column labels, button names); consider centralizing these strings or using more stable attributes/test-ids to reduce brittleness when UI copy changes.
  • The DependencySubTable.verifyRowByName method hardcodes column indices for type/namespace/version; using data-labels or named accessors instead would make the tests more resilient to table layout changes.
  • For CVSS tooltip and popover content, the assertions use full, exact strings; if the explanatory copy is expected to evolve, consider asserting on key phrases rather than the entire text to avoid frequent test updates.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Several selectors rely on visible text (e.g., heading names, column labels, button names); consider centralizing these strings or using more stable attributes/test-ids to reduce brittleness when UI copy changes.
- The `DependencySubTable.verifyRowByName` method hardcodes column indices for type/namespace/version; using data-labels or named accessors instead would make the tests more resilient to table layout changes.
- For CVSS tooltip and popover content, the assertions use full, exact strings; if the explanatory copy is expected to evolve, consider asserting on key phrases rather than the entire text to avoid frequent test updates.

## Individual Comments

### Comment 1
<location path="e2e/tests/ui/pages/sbom-details/vulnerabilities/CvssBreakdownPopover.ts" line_range="48-57" />
<code_context>
+    await expect(rows).toHaveCount(expectedRows);
+  }
+
+  async verifyRowValues(score: string, severity: string, version: string) {
+    await expect(this._table).toBeVisible();
+    const row = this._table
+      .locator("tbody tr")
+      .filter({
+        has: this._page.getByText(severity, { exact: true }),
+      })
+      .filter({
+        has: this._page.locator('td[data-label="Score"]', { hasText: score }),
+      });
+    await expect(row).toBeVisible();
+    await expect(row.locator('td[data-label="Version"]')).toHaveText(version);
+  }
+}
</code_context>
<issue_to_address>
**suggestion (testing):** Row matching logic for CVSS breakdown could be more tightly scoped to avoid accidental matches

In `verifyRowValues`, the row filter uses `this._page.getByText` and a generic `td[data-label="Score"]` locator, which depend on a page-wide text search. If additional tables or similar text appear in the popover, the matcher could pick the wrong row. Please scope these `has` locators to `this._table` (e.g., `this._table.getByText(...)`) or use more specific cell selectors for both severity and score within the row to keep the test robust against layout changes.

Suggested implementation:

```typescript
  async verifyRowCount(expectedRows: number) {
    await expect(this._table).toBeVisible();
    const rows = this._table.locator("tbody tr");
    await expect(rows).toHaveCount(expectedRows);
  }

  async verifyRowValues(score: string, severity: string, version: string) {
    await expect(this._table).toBeVisible();

    const row = this._table
      .locator("tbody tr")
      .filter({
        has: this._table.locator('td[data-label="Severity"]', { hasText: severity }),
      })
      .filter({
        has: this._table.locator('td[data-label="Score"]', { hasText: score }),
      });

    await expect(row).toBeVisible();
    await expect(row.locator('td[data-label="Version"]')).toHaveText(version);
  }

  static async fromCurrentPage(page: Page) {

```

If the severity column uses a different `data-label` (e.g. `"Severity"` may need to be adjusted to match the actual markup), update the selector in `td[data-label="Severity"]` accordingly. Also, if the score cell text includes additional formatting (like parentheses or units), you may want to switch `hasText: score` to a regex or adjust the expected `score` string to match the rendered value exactly.
</issue_to_address>

### Comment 2
<location path="e2e/tests/ui/pages/vulnerability-details/sboms/DependencySubTable.ts" line_range="14-15" />
<code_context>
+    );
+  }
+
+  static async fromCurrentPage(page: Page) {
+    const popover = page.getByRole("dialog", {
+      name: "CVSS Score Breakdown",
</code_context>
<issue_to_address>
**issue:** DependencySubTable helper does not associate the sub-table with a specific SBOM row

The locator `tr:has(> td[colspan]) table` always selects the first expanded dependency sub-table, so if multiple SBOM rows are expanded, the helper can attach to the wrong table and yield misleading test results. Please tighten the association by passing the parent SBOM row (or a more specific locator) into `fromCurrentPage`, or by including the SBOM name in the locator, so that `verifyRowByName` and `verifyNameLink` target the correct SBOM’s dependencies.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Add 28 E2E BDD tests covering 5 gaps identified in TC-4635:
- Gap 1: CVSS Score Breakdown popover on SBOM Vulnerabilities tab (8 tests)
- Gap 2: CVSS score, severity, and version tag on Vulnerability list page (4 tests)
- Gap 3: CVSS Assessment panel on Vulnerability details page (3 tests)
- Gap 4: Related SBOMs tab with status, supplier, and dependency expansion (7 tests)
- Gap 5: Related Advisories tab with multi-type advisory validation (6 tests)

Co-Authored-By: Claude
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

1 participant