Skip to content
This repository was archived by the owner on Sep 11, 2025. It is now read-only.

Commit 3f52c69

Browse files
Add vulnerability table tests
1 parent 1e92bc3 commit 3f52c69

File tree

11 files changed

+242
-37
lines changed

11 files changed

+242
-37
lines changed

tests/ui/pages/Constants.ts

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,23 @@
1-
export const isSorted = (arr: string[], asc: boolean) => {
2-
let sorted = [...arr].sort((a, b) => a.localeCompare(b));
1+
import { expect } from "@playwright/test";
2+
3+
export const sortArray = (arr: string[], asc: boolean) => {
4+
let sorted = [...arr].sort((a, b) =>
5+
a.localeCompare(b, "en", { numeric: true })
6+
);
37
if (!asc) {
48
sorted = sorted.reverse();
59
}
6-
return arr.every((val, i) => val === sorted[i]);
10+
const isSorted = arr.every((val, i) => val === sorted[i]);
11+
return {
12+
isSorted,
13+
sorted,
14+
};
15+
};
16+
17+
export const expectSort = (arr: string[], asc: boolean) => {
18+
const { isSorted, sorted } = sortArray(arr, asc);
19+
expect(
20+
isSorted,
21+
`Received: ${arr.join(", ")} \nExpected: ${sorted.join(", ")}`
22+
).toBe(true);
723
};
Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
// @ts-check
22

3-
import { expect, test } from "@playwright/test";
3+
import { test } from "@playwright/test";
44

55
import { login } from "../../helpers/Auth";
6-
import { isSorted } from "../Constants";
6+
import { expectSort } from "../Constants";
77
import { AdvisoryListPage } from "./AdvisoryListPage";
88

99
test.describe("Sort validations", { tag: "@tier1" }, () => {
1010
test.beforeEach(async ({ page }) => {
1111
await login(page);
1212
});
1313

14-
// skipped until it is fixed in the backend. It is bug, fix it
14+
// TODO
1515
test.skip("Sort", async ({ page }) => {
1616
const listPage = await AdvisoryListPage.build(page);
1717
const table = await listPage.getTable();
@@ -20,12 +20,12 @@ test.describe("Sort validations", { tag: "@tier1" }, () => {
2020

2121
// ID Asc
2222
await table.clickSortBy("ID");
23-
const namesAsc = await columnNameSelector.allInnerTexts();
24-
expect(isSorted(namesAsc, true), "").toBe(true);
23+
const ascList = await columnNameSelector.allInnerTexts();
24+
expectSort(ascList, true);
2525

2626
// ID Desc
2727
await table.clickSortBy("ID");
28-
const namesDesc = await columnNameSelector.allInnerTexts();
29-
expect(isSorted(namesDesc, false)).toBe(true);
28+
const descList = await columnNameSelector.allInnerTexts();
29+
expectSort(descList, false);
3030
});
3131
});

tests/ui/pages/package-list/sort.spec.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
// @ts-check
22

3-
import { expect, test } from "@playwright/test";
3+
import { test } from "@playwright/test";
44

55
import { login } from "../../helpers/Auth";
6-
import { isSorted } from "../Constants";
6+
import { expectSort } from "../Constants";
77
import { PackageListPage } from "./PackageListPage";
88

99
test.describe("Sort validations", { tag: "@tier1" }, () => {
@@ -18,12 +18,12 @@ test.describe("Sort validations", { tag: "@tier1" }, () => {
1818
const columnNameSelector = table._table.locator(`td[data-label="ID"]`);
1919

2020
// ID Asc
21-
const namesAsc = await columnNameSelector.allInnerTexts();
22-
expect(isSorted(namesAsc, true)).toBe(true);
21+
const ascList = await columnNameSelector.allInnerTexts();
22+
expectSort(ascList, true);
2323

2424
// ID Desc
2525
await table.clickSortBy("Name");
26-
const namesDesc = await columnNameSelector.allInnerTexts();
27-
expect(isSorted(namesDesc, false)).toBe(true);
26+
const descList = await columnNameSelector.allInnerTexts();
27+
expectSort(descList, false);
2828
});
2929
});
Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
// @ts-check
22

3-
import { expect, test } from "@playwright/test";
3+
import { test } from "@playwright/test";
44

55
import { login } from "../../../helpers/Auth";
66
import { PackageTab } from "./PackageTab";
7-
import { isSorted } from "../../Constants";
7+
import { expectSort } from "../../Constants";
88

99
test.describe("Sort validations", { tag: "@tier1" }, () => {
1010
test.beforeEach(async ({ page }) => {
@@ -17,13 +17,12 @@ test.describe("Sort validations", { tag: "@tier1" }, () => {
1717

1818
const columnNameSelector = table._table.locator(`td[data-label="Name"]`);
1919

20-
const namesAsc = await columnNameSelector.allInnerTexts();
21-
expect(isSorted(namesAsc, true)).toBe(true);
20+
const ascList = await columnNameSelector.allInnerTexts();
21+
expectSort(ascList, true);
2222

2323
// Reverse sorting
2424
await table.clickSortBy("Name");
25-
const namesDesc = await columnNameSelector.allInnerTexts();
26-
27-
expect(isSorted(namesDesc, false)).toBe(true);
25+
const descList = await columnNameSelector.allInnerTexts();
26+
expectSort(descList, false);
2827
});
2928
});
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { Page } from "@playwright/test";
2+
import { SbomDetailsPage } from "../SbomDetailsPage";
3+
import { Toolbar } from "../../Toolbar";
4+
import { Table } from "../../Table";
5+
import { Pagination } from "../../Pagination";
6+
7+
export class VulnerabilityTab {
8+
private readonly _page: Page;
9+
_detailsPage: SbomDetailsPage;
10+
11+
private constructor(page: Page, layout: SbomDetailsPage) {
12+
this._page = page;
13+
this._detailsPage = layout;
14+
}
15+
16+
static async build(page: Page, sbomName: string) {
17+
const detailsPage = await SbomDetailsPage.build(page, sbomName);
18+
await detailsPage._layout.selectTab("Vulnerabilities");
19+
20+
return new VulnerabilityTab(page, detailsPage);
21+
}
22+
23+
async getToolbar() {
24+
return await Toolbar.build(this._page, "Vulnerability toolbar");
25+
}
26+
27+
async getTable() {
28+
return await Table.build(this._page, "Vulnerability table");
29+
}
30+
31+
async getPagination(top: boolean = true) {
32+
return await Pagination.build(
33+
this._page,
34+
`vulnerability-table-pagination-${top ? "top" : "bottom"}`
35+
);
36+
}
37+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// @ts-check
2+
3+
import { expect, test } from "@playwright/test";
4+
5+
import { login } from "../../../helpers/Auth";
6+
import { VulnerabilityTab } from "./VulnerabilityTab";
7+
8+
test.describe("Columns validations", { tag: "@tier1" }, () => {
9+
test.beforeEach(async ({ page }) => {
10+
await login(page);
11+
});
12+
13+
test("Columns", async ({ page }) => {
14+
const vulnerabilityTab = await VulnerabilityTab.build(page, "quarkus-bom");
15+
16+
const table = await vulnerabilityTab.getTable();
17+
18+
const ids = await table._table
19+
.locator(`td[data-label="Id"]`)
20+
.allInnerTexts();
21+
const idIndex = ids.indexOf("CVE-2023-4853");
22+
expect(idIndex).not.toBe(-1);
23+
24+
// Name
25+
await expect(
26+
table._table.locator(`td[data-label="Id"]`).nth(idIndex)
27+
).toContainText("CVE-2023-4853");
28+
29+
// Description
30+
await expect(
31+
table._table.locator(`td[data-label="Description"]`).nth(idIndex)
32+
).toContainText("quarkus: HTTP security policy bypass");
33+
34+
// Vulnerabilities
35+
await expect(
36+
table._table.locator(`td[data-label="CVSS"]`).nth(idIndex)
37+
).toContainText("High(8.1)");
38+
39+
// Affected dependencies
40+
await expect(
41+
table._table
42+
.locator(`td[data-label="Affected dependencies"]`)
43+
.nth(idIndex)
44+
).toContainText("3");
45+
46+
await table._table
47+
.locator(`td[data-label="Affected dependencies"]`)
48+
.nth(idIndex)
49+
.click();
50+
51+
await expect(
52+
table._table
53+
.locator(`td[data-label="Affected dependencies"]`)
54+
.nth(idIndex + 1)
55+
).toContainText("quarkus-undertow");
56+
await expect(
57+
table._table
58+
.locator(`td[data-label="Affected dependencies"]`)
59+
.nth(idIndex + 1)
60+
).toContainText("quarkus-keycloak-authorization");
61+
await expect(
62+
table._table
63+
.locator(`td[data-label="Affected dependencies"]`)
64+
.nth(idIndex + 1)
65+
).toContainText("quarkus-vertx-http");
66+
});
67+
});
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// @ts-check
2+
3+
import { test } from "@playwright/test";
4+
5+
import { login } from "../../../helpers/Auth";
6+
import { VulnerabilityTab } from "./VulnerabilityTab";
7+
8+
test.describe("Filter validations", { tag: "@tier1" }, () => {
9+
test.beforeEach(async ({ page }) => {
10+
await login(page);
11+
});
12+
13+
// Currently tab has no filters
14+
test.skip("Filters", async ({ page }) => {
15+
const vulnerabilityTab = await VulnerabilityTab.build(page, "quarkus-bom");
16+
17+
const toolbar = await vulnerabilityTab.getToolbar();
18+
const table = await vulnerabilityTab.getTable();
19+
20+
// Full search
21+
await toolbar.applyTextFilter("Filter text", "CVE-2023-4853");
22+
await table.waitUntilDataIsLoaded();
23+
await table.verifyColumnContainsText("Id", "CVE-2023-4853");
24+
25+
// Labels filter
26+
await toolbar.applyMultiSelectFilter("Severity", ["High"]);
27+
await table.waitUntilDataIsLoaded();
28+
await table.verifyColumnContainsText("Id", "CVE-2023-4853");
29+
});
30+
});
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// @ts-check
2+
3+
import { test } from "@playwright/test";
4+
5+
import { login } from "../../../helpers/Auth";
6+
import { VulnerabilityTab } from "./VulnerabilityTab";
7+
8+
test.describe("Pagination validations", { tag: "@tier1" }, () => {
9+
test.beforeEach(async ({ page }) => {
10+
await login(page);
11+
});
12+
13+
test("Navigation button validations", async ({ page }) => {
14+
const vulnerabilityTab = await VulnerabilityTab.build(page, "quarkus-bom");
15+
const pagination = await vulnerabilityTab.getPagination();
16+
17+
await pagination.validatePagination();
18+
});
19+
20+
test("Items per page validations", async ({ page }) => {
21+
const packageTab = await VulnerabilityTab.build(page, "quarkus-bom");
22+
23+
const pagination = await packageTab.getPagination();
24+
const table = await packageTab.getTable();
25+
26+
await pagination.validateItemsPerPage("Id", table);
27+
});
28+
});
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// @ts-check
2+
3+
import { test } from "@playwright/test";
4+
5+
import { login } from "../../../helpers/Auth";
6+
import { VulnerabilityTab } from "./VulnerabilityTab";
7+
import { expectSort } from "../../Constants";
8+
9+
test.describe("Sort validations", { tag: "@tier1" }, () => {
10+
test.beforeEach(async ({ page }) => {
11+
await login(page);
12+
});
13+
14+
test("Sort", async ({ page }) => {
15+
const vulnerabilityTab = await VulnerabilityTab.build(page, "quarkus-bom");
16+
const table = await vulnerabilityTab.getTable();
17+
18+
const columnNameSelector = table._table.locator(`td[data-label="Id"]`);
19+
20+
const ascList = await columnNameSelector.allInnerTexts();
21+
expectSort(ascList, true);
22+
23+
// Reverse sorting
24+
await table.clickSortBy("Id");
25+
const descList = await columnNameSelector.allInnerTexts();
26+
expectSort(descList, false);
27+
});
28+
});
Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
// @ts-check
22

3-
import { expect, test } from "@playwright/test";
3+
import { test } from "@playwright/test";
44

55
import { login } from "../../helpers/Auth";
6-
import { isSorted } from "../Constants";
6+
import { expectSort } from "../Constants";
77
import { SbomListPage } from "./SbomListPage";
88

99
test.describe("Sort validations", { tag: "@tier1" }, () => {
@@ -17,13 +17,12 @@ test.describe("Sort validations", { tag: "@tier1" }, () => {
1717

1818
const columnNameSelector = table._table.locator(`td[data-label="Name"]`);
1919

20-
const namesAsc = await columnNameSelector.allInnerTexts();
21-
expect(isSorted(namesAsc, true)).toBe(true);
20+
const ascList = await columnNameSelector.allInnerTexts();
21+
expectSort(ascList, true);
2222

2323
// Reverse sorting
2424
await table.clickSortBy("Name");
25-
const namesDesc = await columnNameSelector.allInnerTexts();
26-
27-
expect(isSorted(namesDesc, false)).toBe(true);
25+
const desList = await columnNameSelector.allInnerTexts();
26+
expectSort(desList, false);
2827
});
2928
});

0 commit comments

Comments
 (0)