Skip to content

Commit cbe3096

Browse files
authored
test: Add test to delete SBOM and Advisory (guacsec#875)
Signed-off-by: mrrajan <86094767+mrrajan@users.noreply.github.com.>
1 parent 5e48fec commit cbe3096

File tree

13 files changed

+239
-6
lines changed

13 files changed

+239
-6
lines changed

.github/chatmodes/playwright-tester.chatmode.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ mode: 'agent'
3737
- Automatically run test with:
3838
```bash
3939
cd $PROJECT_ROOT/e2e
40-
npx playwright test --project='bdd' --trace on -g "scenario name here" --headed
40+
npx playwright test --project='bdd' --trace on -g "scenario name here"
4141
```
4242
- In case of test failures, the above command launched HTML server to host the test output Press `Ctrl+C` to stop the server
4343

2.05 KB
Binary file not shown.
1.47 KB
Binary file not shown.
12.4 KB
Binary file not shown.
186 KB
Binary file not shown.
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { expect as baseExpect } from "@playwright/test";
2+
import type { DeletionConfirmDialog } from "../pages/ConfirmDialog";
3+
import type { MatcherResult } from "./types";
4+
5+
export interface DialogMatchers {
6+
toHaveTitle(expectedTitle: string): Promise<MatcherResult>;
7+
}
8+
9+
type DialogMatcherDefinitions = {
10+
readonly [K in keyof DialogMatchers]: (
11+
receiver: DeletionConfirmDialog,
12+
...args: Parameters<DialogMatchers[K]>
13+
) => Promise<MatcherResult>;
14+
};
15+
16+
export const dialogAssertions = baseExpect.extend<DialogMatcherDefinitions>({
17+
toHaveTitle: async (
18+
dialog: DeletionConfirmDialog,
19+
expectedTitle: string,
20+
): Promise<MatcherResult> => {
21+
try {
22+
const dialogTitle = dialog.getDeletionConfirmDialogHeading();
23+
await baseExpect(dialogTitle).toHaveText(expectedTitle);
24+
return {
25+
pass: true,
26+
message: () => `Dialog has title "${expectedTitle}"`,
27+
};
28+
} catch (error) {
29+
return {
30+
pass: false,
31+
message: () => (error instanceof Error ? error.message : String(error)),
32+
};
33+
}
34+
},
35+
});

e2e/tests/ui/assertions/index.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,14 @@ import type { Toolbar } from "../pages/Toolbar";
1313
import type { TFilterValue } from "../pages/utils";
1414
import { toolbarAssertions, type ToolbarMatchers } from "./ToolbarMatchers";
1515

16+
import type { DeletionConfirmDialog } from "../pages/ConfirmDialog";
17+
import { dialogAssertions, type DialogMatchers } from "./DialogMatchers";
18+
1619
const merged = mergeExpects(
1720
tableAssertions,
1821
paginationAssertions,
1922
toolbarAssertions,
23+
dialogAssertions,
2024
// Add more custom assertions here
2125
);
2226

@@ -59,6 +63,17 @@ function typedExpect<
5963
> &
6064
ToolbarMatchers<TFilter, TFilterName>;
6165

66+
/**
67+
* Overload from DialogMatchers.ts
68+
*/
69+
function typedExpect(
70+
value: DeletionConfirmDialog,
71+
): Omit<
72+
ReturnType<typeof merged<DeletionConfirmDialog>>,
73+
keyof DialogMatchers
74+
> &
75+
DialogMatchers;
76+
6277
// Default overload
6378
function typedExpect<T>(value: T): ReturnType<typeof merged<T>>;
6479
function typedExpect<T>(value: T): unknown {

e2e/tests/ui/features/@advisory-explorer/advisory-explorer.feature

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,24 @@ Scenario: Display vulnerabilities tied to a single advisory
7070
Examples:
7171
| advisoryName | vulnerabilityID | advisoryType |
7272
| CVE-2023-3223 | CVE-2023-3223 | csaf |
73+
74+
Scenario: Delete an advisory from the Advisory Explorer page
75+
Given User visits Advisory details Page of "<advisoryID>"
76+
When User Clicks on Actions button and Selects Delete option from the drop down
77+
When User select Delete button from the Permanently delete Advisory model window
78+
Then The Advisory deleted message is displayed
79+
And Application Navigates to Advisory list page
80+
And The "<advisoryID>" should not be present on Advisory list page as it is deleted
81+
Examples:
82+
| advisoryID |
83+
| CVE-2025-22130 |
84+
85+
Scenario: Delete an advisory from the Advisory List Page
86+
When User Deletes "<advisoryID>" using the toggle option from Advisory List Page
87+
When User select Delete button from the Permanently delete Advisory model window
88+
Then The Advisory deleted message is displayed
89+
And Application Navigates to Advisory list page
90+
And The "<advisoryID>" should not be present on Advisory list page as it is deleted
91+
Examples:
92+
| advisoryID |
93+
| CVE-2023-1906 |

e2e/tests/ui/features/@advisory-explorer/advisory-explorer.step.ts

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import { createBdd } from "playwright-bdd";
2-
import { expect } from "playwright/test";
2+
import { expect } from "../../assertions";
33
import { ToolbarTable } from "../../helpers/ToolbarTable";
44
import { SearchPage } from "../../helpers/SearchPage";
5+
import { AdvisoryListPage } from "../../pages/advisory-list/AdvisoryListPage";
56
import { test } from "../../fixtures";
7+
import { DeletionConfirmDialog } from "../../pages/ConfirmDialog";
8+
import { DetailsPage } from "../../helpers/DetailsPage";
69

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

@@ -151,3 +154,58 @@ Then(
151154
).toBeVisible();
152155
},
153156
);
157+
158+
When(
159+
"User Deletes {string} using the toggle option from Advisory List Page",
160+
async ({ page }, advisoryID) => {
161+
const listPage = await AdvisoryListPage.build(page);
162+
const toolbar = await listPage.getToolbar();
163+
await toolbar.applyFilter({ "Filter text": advisoryID });
164+
const table = await listPage.getTable();
165+
const rowToDelete = 0;
166+
await table.clickAction("Delete", rowToDelete);
167+
},
168+
);
169+
170+
When(
171+
"User Clicks on Actions button and Selects Delete option from the drop down",
172+
async ({ page }) => {
173+
const details = new DetailsPage(page);
174+
await details.clickOnPageAction("Delete");
175+
},
176+
);
177+
178+
When(
179+
"User select Delete button from the Permanently delete Advisory model window",
180+
async ({ page }) => {
181+
const dialog = await DeletionConfirmDialog.build(page, "Confirm dialog");
182+
await expect(dialog).toHaveTitle(
183+
"Warning alert:Permanently delete Advisory?",
184+
);
185+
await dialog.clickConfirm();
186+
},
187+
);
188+
189+
Then(
190+
"The {string} should not be present on Advisory list page as it is deleted",
191+
async ({ page }, advisoryID: string) => {
192+
const list = await AdvisoryListPage.build(page);
193+
const toolbar = await list.getToolbar();
194+
const table = await list.getTable();
195+
await toolbar.applyFilter({ "Filter text": advisoryID });
196+
await expect(table).toHaveEmptyState();
197+
},
198+
);
199+
200+
Then("Application Navigates to Advisory list page", async ({ page }) => {
201+
await expect(
202+
page.getByRole("heading", { level: 1, name: "Advisories" }),
203+
).toBeVisible();
204+
});
205+
206+
Then("The Advisory deleted message is displayed", async ({ page }) => {
207+
const alertHeading = page.getByRole("heading", { level: 4 }).filter({
208+
hasText: /The Advisory .+ was deleted/,
209+
});
210+
await expect(alertHeading).toBeVisible({ timeout: 10000 });
211+
});

e2e/tests/ui/features/@sbom-explorer/sbom-explorer.feature

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,7 @@ Feature: SBOM Explorer - View SBOM details
119119
When User visits SBOM details Page of "<sbomName>"
120120
When User selects the Tab "Vulnerabilities"
121121
Then Table column "Description" is not sortable
122-
Then Sorting of "Id, Affected dependencies, Published, Updated" Columns Works
123-
#Then Sorting of "CVSS" Columns works
124-
# Bug: https://issues.redhat.com/browse/TC-2598
122+
Then Sorting of "Id, CVSS, Affected dependencies, Published, Updated" Columns Works
125123
Examples:
126124
| sbomName |
127125
| quarkus-bom |
@@ -134,3 +132,25 @@ Feature: SBOM Explorer - View SBOM details
134132
Examples:
135133
| sbomName | Labels |
136134
| ubi9-minimal-container | RANDOM_LABELS |
135+
136+
Scenario Outline: Delete SBOM from SBOM Explorer Page
137+
Given An ingested SBOM "<sbomName>" is available
138+
When User visits SBOM details Page of "<sbomName>"
139+
When User Clicks on Actions button and Selects Delete option from the drop down
140+
When User select Delete button from the Permanently delete SBOM model window
141+
Then The SBOM deleted message is displayed
142+
And Application Navigates to SBOM list page
143+
And The "<sbomName>" should not be present on SBOM list page as it is deleted
144+
Examples:
145+
| sbomName |
146+
| MRG-M-3.0.0 |
147+
148+
Scenario Outline: Delete SBOM from SBOM List Page
149+
When User Deletes "<sbomName>" using the toggle option from SBOM List Page
150+
When User select Delete button from the Permanently delete SBOM model window
151+
Then The SBOM deleted message is displayed
152+
And Application Navigates to SBOM list page
153+
And The "<sbomName>" should not be present on SBOM list page as it is deleted
154+
Examples:
155+
| sbomName |
156+
| rhn_satellite |

0 commit comments

Comments
 (0)