Skip to content

Commit 0899064

Browse files
Merge branch 'main' into feat/importers-crud
2 parents a5c19ca + 2361e9a commit 0899064

13 files changed

Lines changed: 309 additions & 103 deletions

File tree

.env

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
TRUSTIFY_IMAGE=ghcr.io/trustification/trustd:latest
2-
TRUSTIFY_UI_IMAGE=ghcr.io/trustification/trustify-ui:latest
1+
TRUSTIFY_IMAGE=ghcr.io/guacsec/trustd:latest
2+
TRUSTIFY_UI_IMAGE=ghcr.io/guacsec/trustify-ui:latest
33

44
POSTGRESQL_IMAGE=postgres:16
55

.github/workflows/ci-coverage.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
coverage:
1919
runs-on: ubuntu-latest
2020
steps:
21-
- uses: actions/checkout@v4
21+
- uses: actions/checkout@v5
2222
- uses: actions/setup-node@v4
2323
with:
2424
node-version: 22

.github/workflows/ci-e2e-template.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ jobs:
8080
steps:
8181
- name: Download artifact
8282
if: "${{ inputs.artifact != '' }}"
83-
uses: actions/download-artifact@v4
83+
uses: actions/download-artifact@v5
8484
with:
8585
name: ${{ inputs.artifact }}
8686
path: /tmp
@@ -125,7 +125,7 @@ jobs:
125125
steps:
126126
- name: Download artifact
127127
if: "${{ inputs.artifact != '' }}"
128-
uses: actions/download-artifact@v4
128+
uses: actions/download-artifact@v5
129129
with:
130130
name: ${{ inputs.artifact }}
131131
path: /tmp
@@ -135,7 +135,7 @@ jobs:
135135
docker load --input /tmp/${{ inputs.artifact }}.tar
136136
137137
- name: Checkout ui repo
138-
uses: actions/checkout@v4
138+
uses: actions/checkout@v5
139139
- uses: actions/setup-node@v4
140140
with:
141141
node-version: 22

.github/workflows/ci-e2e.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ jobs:
2424

2525
- name: save trustify-ui image
2626
run: |
27-
docker build . -t ghcr.io/trustification/trustify-ui:pr-test -f Dockerfile
28-
docker save -o /tmp/trustify-ui.tar ghcr.io/trustification/trustify-ui:pr-test
27+
docker build . -t ghcr.io/guacsec/trustify-ui:pr-test -f Dockerfile
28+
docker save -o /tmp/trustify-ui.tar ghcr.io/guacsec/trustify-ui:pr-test
2929
3030
- name: Upload trustify-ui image as artifact
3131
uses: actions/upload-artifact@v4
@@ -75,5 +75,5 @@ jobs:
7575
uses: ./.github/workflows/ci-e2e-template.yaml
7676
with:
7777
artifact: trustify-ui
78-
ui_image: ghcr.io/trustification/trustify-ui:pr-test
79-
server_image: ghcr.io/trustification/trustd:${{ needs.discover-envs-for-e2e-ci.outputs.image_tag }}
78+
ui_image: ghcr.io/guacsec/trustify-ui:pr-test
79+
server_image: ghcr.io/guacsec/trustd:${{ needs.discover-envs-for-e2e-ci.outputs.image_tag }}

.github/workflows/image-build.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ jobs:
4242
password: ${{ secrets.GITHUB_TOKEN }}
4343
registry: ghcr.io
4444
- name: Generate artifact attestation
45-
uses: actions/attest-build-provenance@v2
45+
uses: actions/attest-build-provenance@v3
4646
with:
4747
subject-name: ghcr.io/${{ github.repository_owner }}/trustify-ui
4848
subject-digest: ${{ needs.ui-image-build.outputs.digest }}

client/src/app/pages/sbom-list/sbom-list.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export const SbomList: React.FC = () => {
1717
<PageSection hasBodyWrapper={false}>
1818
<div>
1919
<SbomSearchProvider>
20-
<SbomToolbar showFilters />
20+
<SbomToolbar showFilters showActions />
2121
<SbomTable />
2222
</SbomSearchProvider>
2323
</div>

client/src/app/pages/sbom-list/sbom-toolbar.tsx

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,13 @@ import { SbomSearchContext } from "./sbom-context";
1616

1717
interface SbomToolbarProps {
1818
showFilters?: boolean;
19+
showActions?: boolean;
1920
}
2021

21-
export const SbomToolbar: React.FC<SbomToolbarProps> = ({ showFilters }) => {
22+
export const SbomToolbar: React.FC<SbomToolbarProps> = ({
23+
showFilters,
24+
showActions,
25+
}) => {
2226
const navigate = useNavigate();
2327

2428
const { tableControls } = React.useContext(SbomSearchContext);
@@ -36,11 +40,16 @@ export const SbomToolbar: React.FC<SbomToolbarProps> = ({ showFilters }) => {
3640
<Toolbar {...toolbarProps} aria-label="sbom-toolbar">
3741
<ToolbarContent>
3842
{showFilters && <FilterToolbar {...filterToolbarProps} />}
39-
<ToolbarItem>
40-
<Button variant="primary" onClick={() => navigate(Paths.sbomUpload)}>
41-
Upload SBOM
42-
</Button>
43-
</ToolbarItem>
43+
{showActions && (
44+
<ToolbarItem>
45+
<Button
46+
variant="primary"
47+
onClick={() => navigate(Paths.sbomUpload)}
48+
>
49+
Upload SBOM
50+
</Button>
51+
</ToolbarItem>
52+
)}
4453
<ToolbarItem {...paginationToolbarItemProps}>
4554
<SimplePagination
4655
idPrefix="sbom-table"

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

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,61 @@ Feature: Advisory Explorer
22
Background: Authentication
33
Given User is authenticated
44

5+
# Search for advisories
6+
Scenario: Search for an advisory using the general search bar
7+
8+
When User searches for an advisory named "<advisoryID>" in the general search bar
9+
10+
Then The advisory "<advisoryID>" shows in the results
11+
12+
Examples:
13+
| advisoryID |
14+
| CVE-2024-26308 |
15+
16+
Scenario: Search for an advisory using the dedicated search bar
17+
18+
When User searches for "<advisoryID>" in the dedicated search bar
19+
20+
Then The advisory "<advisoryID>" shows in the results
21+
22+
Examples:
23+
| advisoryID |
24+
| CVE-2024-26308 |
25+
26+
# Advisory Explorer
27+
Scenario: Display an overview of an advisory
28+
29+
When User visits Advisory details Page of "<advisoryID>"
30+
31+
Then The page title is "<advisoryID>"
32+
Then The "Download" action is available
33+
34+
Examples:
35+
| advisoryID |
36+
| CVE-2024-26308 |
37+
38+
Scenario: Download an advisory
39+
40+
When User visits Advisory details Page of "<advisoryID>"
41+
42+
Then "Download Advisory" action is invoked and downloaded filename is "<fileName>"
43+
44+
Examples:
45+
| advisoryID | fileName |
46+
| CVE-2024-26308 | CVE-2024-26308.json |
47+
48+
Scenario: Display the Info tab
49+
50+
When User visits Advisory details Page of "<advisoryID>"
51+
52+
Then The "Overview" panel is visible
53+
Then The "Publisher" panel is visible
54+
Then The "Tracking" panel is visible
55+
56+
Examples:
57+
| advisoryID |
58+
| CVE-2024-26308 |
59+
560
# Advisory Vulnerabilities
661
Scenario: Display vulnerabilities tied to a single advisory
762
Given User visits Advisory details Page of "<advisoryName>" with type "<advisoryType>"

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

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,15 @@ export const { Given, When, Then } = createBdd(test);
88

99
const VULN_TABLE_NAME = "vulnerability table";
1010

11+
Given(
12+
"User visits Advisory details Page of {string}",
13+
async ({ page }, advisoryID) => {
14+
const searchPage = new SearchPage(page, "Advisories");
15+
await searchPage.dedicatedSearch(advisoryID);
16+
await page.getByRole("link", { name: advisoryID, exact: true }).click();
17+
},
18+
);
19+
1120
Given(
1221
"User visits Advisory details Page of {string} with type {string}",
1322
async ({ page }, advisoryName, advisoryType) => {
@@ -18,6 +27,59 @@ Given(
1827
},
1928
);
2029

30+
// Advisory Search
31+
When(
32+
"User searches for an advisory named {string} in the general search bar",
33+
async ({ page }, item) => {
34+
const searchPage = new SearchPage(page, "Dashboard");
35+
await searchPage.generalSearch("Advisories", item);
36+
},
37+
);
38+
39+
When(
40+
"User searches for {string} in the dedicated search bar",
41+
async ({ page }, advisoryID) => {
42+
const searchPage = new SearchPage(page, "Advisories");
43+
await searchPage.dedicatedSearch(advisoryID);
44+
},
45+
);
46+
47+
Then(
48+
"The advisory {string} shows in the results",
49+
async ({ page }, advisoryID) => {
50+
await expect(
51+
page.getByRole("gridcell").filter({ hasText: advisoryID }),
52+
).toBeVisible();
53+
},
54+
);
55+
56+
// Advisory Explorer
57+
Then(
58+
"The vulnerabilities table is sorted by {string}",
59+
async ({ page }, columnName) => {
60+
const toolbarTable = new ToolbarTable(page, VULNERABILITIES_TABLE_NAME);
61+
await toolbarTable.verifyTableIsSortedBy(columnName);
62+
},
63+
);
64+
65+
Then(
66+
"The vulnerabilities table total results is {int}",
67+
async ({ page }, totalResults) => {
68+
const toolbarTable = new ToolbarTable(page, VULNERABILITIES_TABLE_NAME);
69+
await toolbarTable.verifyPaginationHasTotalResults(totalResults);
70+
},
71+
);
72+
73+
Then(
74+
"The {string} column of the vulnerability table contains {string}",
75+
async ({ page }, columnName, expectedValue) => {
76+
const toolbarTable = new ToolbarTable(page, VULNERABILITIES_TABLE_NAME);
77+
await toolbarTable.verifyColumnContainsText(columnName, expectedValue);
78+
},
79+
);
80+
81+
// Advisory Explorer / Vulenrabilities
82+
2183
Then(
2284
"User navigates to the Vulnerabilities tab on the Advisory Overview page",
2385
async ({ page }) => {

e2e/tests/ui/helpers/DetailsPage.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,34 @@ export class DetailsPage {
2222
await this.page.getByRole("menuitem", { name: actionName }).click();
2323
}
2424

25+
async clickOnPageButton(buttonName: string) {
26+
await this.page.getByRole("button", { name: buttonName }).click();
27+
}
28+
2529
async verifyPageHeader(header: string) {
2630
await expect(this.page.getByRole("heading")).toContainText(header);
2731
}
2832

33+
async verifyActionIsAvailable(actionName: string) {
34+
await this.page.getByRole("button", { name: "Actions" }).click();
35+
await expect(
36+
this.page.getByRole("menuitem", { name: actionName }),
37+
).toBeVisible();
38+
}
39+
40+
async verifyButtonIsVisible(button: string) {
41+
await expect(this.page.getByRole("button", { name: button })).toBeVisible();
42+
}
43+
44+
async verifyPanelIsVisible(panel: string) {
45+
await expect(
46+
this.page
47+
.locator(".pf-v6-c-card__title-text")
48+
.filter({ hasText: panel })
49+
.first(),
50+
).toBeVisible();
51+
}
52+
2953
async verifyTabIsSelected(tabName: string) {
3054
await expect(this.page.getByRole("tab", { name: tabName })).toHaveAttribute(
3155
"aria-selected",

0 commit comments

Comments
 (0)