Skip to content

Commit

Permalink
add project feature v0.51
Browse files Browse the repository at this point in the history
  • Loading branch information
elAlmani committed Feb 1, 2025
1 parent 0297b2e commit a83bb59
Show file tree
Hide file tree
Showing 11 changed files with 365 additions and 32 deletions.
Original file line number Diff line number Diff line change
@@ -1,26 +1,32 @@
@test
Feature:
@skip # This is being skipped as it is done in provisioning.setup.feature
Scenario: Upload Default BOM To Recently Created Test Project
Given the admin user logs in to DependencyTrack
Then the dashboard should be visible
Then the user navigates to project page
Then the user navigates to "projectsTab" page
Then the user opens the project with the name "test-project01"
And the user navigates to project "components" tab
And the user uploads default BOM

Scenario: Validate Test Project With Uploaded BOM
Given the admin user logs in to DependencyTrack
Then the dashboard should be visible
Then the user navigates to project page
Then the user navigates to "projectsTab" page
Then the user opens the project with the name "test-project01"
Then the user verifies "components" with the badge number of 238 on current project
Then the user verifies "services" with the badge number of 19 on current project
Then the user verifies "dependencyGraph" with the badge number of 1 on current project
Then the user verifies "exploitPredictions" with the badge number of 3 on current project
Then the user verifies Audit Vulnerabilities with the badge number of 3 excluding and 3 including aliases on current project
Then the user verifies Policy Violations with the badge number of 0 total 0 info 0 warn 0 fail violations on current project
Then the user verifies Policy Violations with the badge number of 238 total 0 info 0 warn 238 fail violations on current project

Scenario:
# Todo
Scenario: Validate each Project Tab
Given the admin user logs in to DependencyTrack
Then the dashboard should be visible
Then the user navigates to "projectsTab" page
Then the user opens the project with the name "test-project01"

@skip # Skipping as it is unnecessary to delete
Scenario: Delete Project Afterwards
Expand Down
38 changes: 30 additions & 8 deletions e2e/playwright-tests/features/provisioning.setup.feature
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Feature:
Scenario: Cleanup Test Users Before Tests
Given the admin user logs in to DependencyTrack
Then the dashboard should be visible
Then the user navigates to administration page
Then the user navigates to "administrationTab" page
And the user navigates to administration menu "accessManagement"
And the user clicks on access-management submenu "managedUsers"
Then the user deletes the following test users if they exist
Expand All @@ -24,7 +24,7 @@ Feature:
Scenario: Create Test Users
Given the admin user logs in to DependencyTrack
Then the dashboard should be visible
Then the user navigates to administration page
Then the user navigates to "administrationTab" page
And the user navigates to administration menu "accessManagement"
And the user clicks on access-management submenu "managedUsers"
Then the user creates the following test users
Expand All @@ -42,10 +42,32 @@ Feature:
| test-user11 |
| test-user12 |

Scenario: Delete All Test Policies
Given the admin user logs in to DependencyTrack
Then the dashboard should be visible
Then the user navigates to "policyManagementTab" page
Then the user deletes the following test policies if they exist
| policyName |
| test-policy01 |

Scenario: Create Test Policies
Given the admin user logs in to DependencyTrack
Then the dashboard should be visible
Then the user navigates to "policyManagementTab" page
Then the user creates the following test policies
| policyName |
| test-policy01 |
And the user updates a policy with the following values
| policyName | newPolicyName | operator | violationState |
| test-policy01 | test-policy01 | ANY | FAIL |
And the user adds conditions to "test-policy01" with the following values
| conditionSubject | conditionOperator | conditionInputValue |
| AGE | > | P1D |

Scenario: Delete All Test Project
Given the admin user logs in to DependencyTrack
Then the dashboard should be visible
Then the user navigates to project page
Then the user navigates to "projectsTab" page
And the user deletes the following test projects if they exist
| name |
| test-project01 |
Expand All @@ -54,19 +76,19 @@ Feature:
Scenario: Create Test Project With Default BOM
Given the admin user logs in to DependencyTrack
Then the dashboard should be visible
Then the user navigates to project page
Then the user navigates to "projectsTab" page
And the user creates projects with the following values
| name | classifier | version | isLastVersion | team | parent | description | tag |
| test-project01 | APPLICATION | | | | | | |
| test-project02 | APPLICATION | | | | | | |
#Then the user opens the project with the name "test-project01"
#And the user navigates to project "components" tab
#And the user uploads default BOM
Then the user opens the project with the name "test-project01"
And the user navigates to project "components" tab
And the user uploads default BOM

Scenario: Provide Test Users With Respective Permissions
Given the admin user logs in to DependencyTrack
Then the dashboard should be visible
Then the user navigates to administration page
Then the user navigates to "administrationTab" page
And the user navigates to administration menu "accessManagement"
And the user clicks on access-management submenu "managedUsers"
Then the user provides "test-user01" with the following permissions
Expand Down
7 changes: 6 additions & 1 deletion e2e/playwright-tests/fixtures/fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
ProjectComponentsPage,
ProjectPage, SelectedProjectPage
} from "../page-objects/project.pom";
import {PolicyPage} from "../page-objects/policy-management.pom";


// export custom test fixtures
Expand All @@ -46,6 +47,7 @@ export const test = base.extend<
dashboardPage: DashboardPage;
navBarPage: NavigationParPage;
notificationToast: NotificationToast;
policyPage: PolicyPage;
}>({
administrationPage: async ({ page }, use) => {
await use(new AdministrationPage(page));
Expand Down Expand Up @@ -91,7 +93,10 @@ export const test = base.extend<
},
notificationToast: async ({ page }, use) => {
await use(new NotificationToast(page));
}
},
policyPage: async ({ page }, use) => {
await use(new PolicyPage(page));
},
});

// export changes
Expand Down
7 changes: 1 addition & 6 deletions e2e/playwright-tests/page-objects/login.pom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,30 +17,25 @@ export class LoginPage {
this.password = page.getByPlaceholder(getValue("message","password"));
this.submitButton = page.getByRole('button', { name: getValue("message", "login") });
this.loginDescription = page.locator('.text-muted');
this.loginErrorPopup = page.locator('.modal-content'); //language.json key -> login_unauthorized
this.loginErrorPopup = page.locator('.modal-content');
}

async login(username: string, password: string) {
await this.username.fill(username);
await this.password.fill(password);
await this.submitButton.click();
await this.page.waitForTimeout(2000);
}

async isLoginPageVisible() {
await expect(this.page).toHaveTitle(/Login/);
await expect(this.heading).toBeVisible();
}

async getLoginDescription() {
return await this.loginDescription.innerText();
}

async verifyLoginErrorPopup() {
await expect(this.loginErrorPopup).toBeVisible();
await expect(this.loginErrorPopup).toContainText(getValue("message", "login_unauthorized"));
}

async closeLoginErrorPopup() {
await this.loginErrorPopup.locator('button').click();
}
Expand Down
18 changes: 18 additions & 0 deletions e2e/playwright-tests/page-objects/notification-toast.pom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,22 @@ export class NotificationToast {
await expect(this.successToast).toContainText(getValue("message", "bom_uploaded"));
await this.successToast.click();
}

async verifySuccessfulPolicyCreatedToast() {
await expect(this.successToast).toBeVisible();
await expect(this.successToast).toContainText(getValue("message", "policy_created"));
await this.successToast.click();
}

async verifySuccessfulPolicyDeletedToast() {
await expect(this.successToast).toBeVisible();
await expect(this.successToast).toContainText(getValue("message", "policy_deleted"));
await this.successToast.click();
}

async verifySuccessfulConditionDeletedToast() {
await expect(this.successToast).toBeVisible();
await expect(this.successToast).toContainText(getValue("message", "condition_deleted"));
await this.successToast.click();
}
}
122 changes: 122 additions & 0 deletions e2e/playwright-tests/page-objects/policy-management.pom.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import {Page, Locator, expect} from '@playwright/test';
import { getValue } from "../utilities/utils";
import {NotificationToast} from "./notification-toast.pom";

export class PolicyPage {
page: Page;
createPolicyButton: Locator;
searchFieldInput: Locator;

modalContent: Locator;

policyNameInput: Locator;
policyCreationCreateButton: Locator;
policyCreationClosePolicyButton: Locator;

policyDetailView: Locator;

policyDetailNameInput: Locator;
policyDetailOperatorSelect: Locator;
policyDetailViolationStateSelect: Locator;
policyDetailConditionSubjectSelect: Locator;
policyDetailConditionOperatorSelect: Locator;
policyDetailConditionInput: Locator;

policyDetailAddConditionButton: Locator;
policyDetailDeleteConditionButton: Locator;

policyDeletionButton: Locator;

constructor(page: Page) {
this.page = page;

this.createPolicyButton = page.getByRole('button', { name: getValue("message", "create_policy") });
this.searchFieldInput = page.locator('.search-input').first(); // Todo nach talk mit Niklas .first() removen

this.modalContent = page.locator('.modal-content');

// Create Policy
this.policyNameInput = this.modalContent.locator('#identifier-input');
this.policyCreationCreateButton = this.modalContent.getByRole('button', { name: getValue("message", "create") });
this.policyCreationClosePolicyButton = this.modalContent.getByRole('button', { name: getValue("message", "close") });

this.policyDetailView = page.locator('.detail-view');

// Edit Policy
this.policyDetailNameInput = this.policyDetailView.locator('#identifier-input');
this.policyDetailOperatorSelect = this.policyDetailView.locator('#input-repository-type-input').first();// getByLabel(getValue("message", "operator"));
this.policyDetailViolationStateSelect = this.policyDetailView.locator('#input-repository-type-input').last(); // .getByLabel(getValue("message", "violation_state"));
this.policyDetailConditionSubjectSelect = this.policyDetailView.locator('#input-subject-input');
this.policyDetailConditionOperatorSelect = this.policyDetailView.locator('#input-operator-input');
this.policyDetailConditionInput = this.policyDetailView.locator('#input-value-input');

this.policyDetailAddConditionButton = this.policyDetailView.locator('button.btn.pull-right').filter({ has: this.page.locator('.fa.fa-plus-square') }).first();
this.policyDetailDeleteConditionButton = this.policyDetailView.locator('button.btn.pull-right').filter({ has: this.page.locator('.fa.fa-trash-o') }).first();

// Delete Policy
this.policyDeletionButton = this.policyDetailView.getByRole('button', { name: getValue("message", "delete_policy")})
}

async clickOnCreatePolicy() {
await this.createPolicyButton.click();
}

async fillSearchFieldInput(search: string) {
await this.searchFieldInput.clear();
await this.searchFieldInput.pressSequentially(search);
await this.page.waitForTimeout(1000);
}

async ClearSearchFieldInput() {
await this.searchFieldInput.clear();
}

async createPolicy(policyName: string) {
await expect(this.modalContent).toBeVisible();
await expect(this.modalContent).toContainText(getValue("message", "create_policy"));

await this.policyNameInput.pressSequentially(policyName);
await this.policyCreationCreateButton.click();
}

async togglePolicyDetailView(policyName: string) {
await this.fillSearchFieldInput(policyName);
await this.page.getByRole('cell', { name: policyName }).click();
}

async addConditionToPolicy(subject: string, operator: string, value: string) {
await this.policyDetailAddConditionButton.click();
await this.policyDetailConditionSubjectSelect.selectOption(subject);
await this.policyDetailConditionOperatorSelect.selectOption(operator);
await this.policyDetailConditionInput.pressSequentially(value);
}

async deleteAllConditions() {
const notificationToast = new NotificationToast(this.page);

while (await this.policyDetailDeleteConditionButton.count() > 0) {
await this.policyDetailDeleteConditionButton.click();
await notificationToast.verifySuccessfulConditionDeletedToast();
await this.page.waitForTimeout(1000);
}
}

async deletePolicy() {
await expect(this.policyDetailView).toBeVisible();
await this.policyDeletionButton.click();
}

async updatePolicyName(newPolicyName: string) {
await this.policyDetailNameInput.clear();
await this.policyDetailNameInput.pressSequentially(newPolicyName);
}

async updatePolicyOperator(operator: string) {
await this.policyDetailOperatorSelect.selectOption(operator);
}

async updatePolicyViolationState(violationState: string) {
await this.policyDetailViolationStateSelect.selectOption(violationState);
}

}
14 changes: 13 additions & 1 deletion e2e/playwright-tests/page-objects/project.pom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export class ProjectModal {
this.modalContent = page.locator('.modal-content');
this.projectNameInput = this.modalContent.locator('#project-name-input-input');
this.projectVersionInput = this.modalContent.locator('#project-version-input-input');
this.projectIsLastVersionSlider = this.modalContent.locator('#project-create-islatest-input');
this.projectIsLastVersionSlider = this.modalContent.locator('#project-create-islatest .switch-slider'); // #project-create-islatest-input
this.projectClassifierSelect = this.modalContent.locator('#v-classifier-input-input');
this.projectTeamSelect = this.modalContent.locator('#v-team-input-input');
this.projectParentSelect = this.modalContent.locator('##multiselect');
Expand Down Expand Up @@ -266,6 +266,11 @@ export class ProjectComponentsPage {
bomUploadResetButton: Locator;
bomUploadConfirmButton: Locator;

downloadBomInventoryButton: Locator;
downloadBomInventoryWithVulnerabilitiesButton: Locator;

downloadComponentsCSVButton: Locator;

constructor(page: Page) {
this.page = page;
this.addComponentButton = page.getByRole('button', { name: getValue("message", "add_component") });
Expand All @@ -282,6 +287,13 @@ export class ProjectComponentsPage {
this.bomUploadCancelButton = this.modalContent.getByRole('button', { name: getValue("message", "cancel") });
this.bomUploadResetButton = this.modalContent.getByRole('button', { name: getValue("message", "reset") });
this.bomUploadConfirmButton = this.modalContent.getByRole('button', { name: getValue("message", "upload") });

// BOM Download
this.downloadBomInventoryButton = this.page.locator('.dropdown-menu.show').getByRole('menuitem', { name: getValue("message", "inventory") });
this.downloadBomInventoryWithVulnerabilitiesButton = this.page.locator('.dropdown-menu.show').getByRole('menuitem', { name: getValue("message", "inventory_with_vulnerabilities") });

// Components Download
this.downloadComponentsCSVButton = this.page.locator('.dropdown-menu.show').getByRole('menuitem', { name: getValue("message", "csv_filetype") });
}

async uploadBom(filePathFromProjectRoot?: string) {
Expand Down
Loading

0 comments on commit a83bb59

Please sign in to comment.