Skip to content
This repository was archived by the owner on Sep 11, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 8 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
18 changes: 18 additions & 0 deletions tests/ui/features/@advisory-explorer/advisory-explorer.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
Feature: Advisory Explorer
Background: Authentication
Given User is authenticated

# Advisory Vulnerabilities
Scenario: Display vulnerabilities tied to a single advisory
Given User visits Advisory details Page of "<advisoryName>"
Then User navigates to the Vulnerabilites tab on the Advisory Overview page
Then Pagination of Vulnerabilities list works
Then A list of all active vulnerabilites tied to the advisory should display
And The ID, Title, Discovery, Release, Score and CWE information should be visible for each vulnerability
And The vulnerabilities should be sorted by ID by default
And User visits Vulnerability details Page of "<vulnerabilityID>" by clicking it

Examples:
| advisoryName | vulnerabilityID |
| CVE-2023-3223 | CVE-2023-3223 |

92 changes: 92 additions & 0 deletions tests/ui/features/@advisory-explorer/advisory-explorer.step.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { createBdd } from "playwright-bdd";
import { expect } from "playwright/test";
import { ToolbarTable } from "../../helpers/ToolbarTable";
import { SearchPage } from "../../helpers/SearchPage";

export const { Given, When, Then } = createBdd();

const VULN_TABLE_NAME = "vulnerability table";
const COLUMN_LABELS = ["ID", "Title", "Discovery", "Release", "Score", "CWE"];

Given(
"User visits Advisory details Page of {string}",
async ({ page }, advisoryName) => {
const searchPage = new SearchPage(page, "Advisories");
await searchPage.dedicatedSearch(advisoryName);
await page.getByRole("link", { name: advisoryName }).click();
}
);

Then(
"User navigates to the Vulnerabilites tab on the Advisory Overview page",
async ({ page }) => {
await page.getByRole("tab", { name: "Vulnerabilities" }).click();
}
);

Then("Pagination of Vulnerabilities list works", async ({ page }) => {
const toolbarTable = new ToolbarTable(page, VULN_TABLE_NAME);
const vulnTableTopPagination = `xpath=//div[@id="vulnerability-table-pagination-top"]`;
await toolbarTable.verifyPagination(vulnTableTopPagination);
});

Then(
"A list of all active vulnerabilites tied to the advisory should display",
async ({ page }) => {
const totalItemsLocator = page
.locator(
"#vulnerability-table-pagination-top .pf-v6-c-pagination__page-menu"
)
.first();

await expect(totalItemsLocator).toBeVisible();

const totalText = await totalItemsLocator.textContent();
const match = totalText?.match(/of\s+(\d+)/);
expect(match, "unable to parse pagination total").not.toBeNull();

const total = Number(match![1]);
expect(total).toBeGreaterThan(0);
}
);

Then(
"The ID, Title, Discovery, Release, Score and CWE information should be visible for each vulnerability",
async ({ page }) => {
for (const label of COLUMN_LABELS) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggestion: Instead of creating column name list, the column headers can be parsed from the BDD statement like https://github.com/trustification/trustify-tests/blob/main/tests/ui/features/%40sbom-explorer/sbom-explorer.step.ts#L184

const header = page.getByRole("columnheader", { name: label });
if (await header.count()) {
await expect(header).toBeVisible();
} else {
await expect(page.getByRole("button", { name: label })).toBeVisible();
}
}
}
);

Then(
"The vulnerabilities should be sorted by ID by default",
async ({ page }) => {
const toolbarTable = new ToolbarTable(page, VULN_TABLE_NAME);
await toolbarTable.verifyTableIsSortedBy("ID");
}
);

Then(
"User visits Vulnerability details Page of {string} by clicking it",
async ({ page }, vulnerabilityID) => {
const link = page.getByRole("link", { name: vulnerabilityID });

await Promise.all([
page.waitForURL(new RegExp(`/vulnerabilities/${vulnerabilityID}$`)),
link.click(),
]);

await expect(
page.getByRole("heading", {
level: 1,
name: new RegExp(`^${vulnerabilityID}\\s*$`),
})
).toBeVisible();
}
);
20 changes: 8 additions & 12 deletions tests/ui/features/advisory-explorer.feature
Original file line number Diff line number Diff line change
Expand Up @@ -62,19 +62,15 @@ Scenario: Display notes about a single advisory

# Advisory Vulnerabilities
Scenario: Display vulnerabilities tied to a single advisory
Given User is on the Home page
When User navigates to the Advisory Explorer page
And User navigates to the Vulnerabilites tab on the Advisory Overview page
Given User visits Advisory details Page of "<advisoryName>"
Then User navigates to the Vulnerabilites tab on the Advisory Overview page
Then A list of all active vulnerabilites tied to the advisory should display
And The ID, Title, Discovery, Release, Score and CWE information should be visible for each vulnerability
And The vulnerabilities should be sorted by ID by default
And Each vulnerability should be expandable
And User visits Vulnerability details Page of "<vulnerabilityID>" by clicking it

Examples:
| advisoryName | vulnerabilityID |
| GHSA-526j-mv3p-f4vv | CVE-2025-54379 |


Scenario: Display detailed information about a single vulnerability tied to a single advisory
Given User is on the Home page
When User navigates to the Advisory Explorer page
And User navigates to the Vulnerabilites tab on the Advisory Overview page
And User expands the row of a selected vulnerability
Then A list of all affected products, separated by status, should display
And Each product should display a link to a remediation
And All notes on a vulnerability should be displayed underneath the list of products