diff --git a/frontend/src/__tests__/cypress/cypress/fixtures/e2e/dataScienceProjects/testClusterStorageCreation.yaml b/frontend/src/__tests__/cypress/cypress/fixtures/e2e/dataScienceProjects/testClusterStorageCreation.yaml new file mode 100644 index 0000000000..28d8de03b2 --- /dev/null +++ b/frontend/src/__tests__/cypress/cypress/fixtures/e2e/dataScienceProjects/testClusterStorageCreation.yaml @@ -0,0 +1,5 @@ +# testClusterStorageCreation.cy.ts Test Data # +projectPVStorageResourceName: "cy-pv-storage-test" +pvStorageName: "cy-pv-storage" +pvStorageDescription: "Test Description of PV Storage" +pvStorageNameEdited: "cy-pv-storage-edited" diff --git a/frontend/src/__tests__/cypress/cypress/pages/clusterStorage.ts b/frontend/src/__tests__/cypress/cypress/pages/clusterStorage.ts index f12e0aa66d..061484dd95 100644 --- a/frontend/src/__tests__/cypress/cypress/pages/clusterStorage.ts +++ b/frontend/src/__tests__/cypress/cypress/pages/clusterStorage.ts @@ -125,6 +125,10 @@ class ClusterStorageModal extends Modal { return this.find().findByTestId('modal-submit-button'); } + findPVStorageSizeValue() { + return this.find().find('[aria-label="Input"]'); + } + private findPVSizeSelectButton() { return this.find().findByTestId('value-unit-select'); } @@ -234,6 +238,10 @@ class ClusterStorage { findCreateButtonFromActions() { return cy.findByTestId('actions-cluster-storage-button'); } + + findKebabToggle() { + return cy.get('button[aria-label="Kebab toggle"]'); + } } export const clusterStorage = new ClusterStorage(); diff --git a/frontend/src/__tests__/cypress/cypress/tests/e2e/dataScienceProjects/clusterStorage/testClusterStorageCreation.cy.ts b/frontend/src/__tests__/cypress/cypress/tests/e2e/dataScienceProjects/clusterStorage/testClusterStorageCreation.cy.ts new file mode 100644 index 0000000000..634e6af7b4 --- /dev/null +++ b/frontend/src/__tests__/cypress/cypress/tests/e2e/dataScienceProjects/clusterStorage/testClusterStorageCreation.cy.ts @@ -0,0 +1,105 @@ +import type { DataScienceProjectData, DashboardConfig } from '~/__tests__/cypress/cypress/types'; +import { projectDetails, projectListPage } from '~/__tests__/cypress/cypress/pages/projects'; +import { HTPASSWD_CLUSTER_ADMIN_USER } from '~/__tests__/cypress/cypress/utils/e2eUsers'; +import { loadDSPFixture } from '~/__tests__/cypress/cypress/utils/dataLoader'; +import { createCleanProject } from '~/__tests__/cypress/cypress/utils/projectChecker'; +import { deleteOpenShiftProject } from '~/__tests__/cypress/cypress/utils/oc_commands/project'; +import { + clusterStorage, + addClusterStorageModal, + updateClusterStorageModal, +} from '~/__tests__/cypress/cypress/pages/clusterStorage'; +import { deleteModal } from '~/__tests__/cypress/cypress/pages/components/DeleteModal'; + +describe('Verify Cluster Storage - Creating, Editing and Deleting', () => { + let testData: DataScienceProjectData; + let dashboardConfig: DashboardConfig; + let projectName: string; + let pvStorageName: string; + let pvStorageDescription: string; + let pvStorageNameEdited: string; + + // Setup: Load test data and ensure clean state + before(() => { + // Retrieve the dashboard configuration + cy.getDashboardConfig().then((config) => { + dashboardConfig = config as DashboardConfig; + cy.log('Dashboard Config:', JSON.stringify(dashboardConfig, null, 2)); + const { pvcSize } = dashboardConfig.notebookController; + cy.log(`Value of PVC Size: ${String(pvcSize)}`); + }); + return loadDSPFixture('e2e/dataScienceProjects/testClusterStorageCreation.yaml') + .then((fixtureData: DataScienceProjectData) => { + testData = fixtureData; + projectName = testData.projectPVStorageResourceName; + pvStorageName = testData.pvStorageName; + pvStorageDescription = testData.pvStorageDescription; + pvStorageNameEdited = testData.pvStorageNameEdited; + if (!projectName) { + throw new Error('Project name is undefined or empty in the loaded fixture'); + } + cy.log(`Loaded project name: ${projectName}`); + return createCleanProject(projectName); + }) + .then(() => { + cy.log(`Project ${projectName} confirmed to be created and verified successfully`); + }); + }); + after(() => { + // Delete provisioned Project + if (projectName) { + cy.log(`Deleting Project ${projectName} after the test has finished.`); + deleteOpenShiftProject(projectName); + } + }); + + it( + 'Create, Edit and Delete a Persistent Volume Storage', + { tags: ['@Sanity', '@SanitySet1', '@ODS-1824', '@Dashboard'] }, + () => { + // Authentication and navigation + cy.step('Log into the application'); + cy.visitWithLogin('/', HTPASSWD_CLUSTER_ADMIN_USER); + + // Project navigation and navigate to the Cluster Storage tab + cy.step( + `Navigate to the Project list tab and search for ${testData.projectPVStorageResourceName}`, + ); + projectListPage.navigate(); + projectListPage.filterProjectByName(testData.projectPVStorageResourceName); + projectListPage.findProjectLink(testData.projectPVStorageResourceName).click(); + + //Navigate to Cluster Storage and click to Add Storage + cy.step('Navigate to Cluster Storage and click to create Cluster Storage'); + projectDetails.findSectionTab('cluster-storages').click(); + clusterStorage.findCreateButton().click(); + + // Enter validate Cluster Storage details into the Cluster Storage Modal + cy.step('Enter valid Cluster Storage details and verify creation'); + addClusterStorageModal.findNameInput().type(pvStorageName); + addClusterStorageModal.findDescriptionInput().type(pvStorageDescription); + const numericPvcSize = dashboardConfig.notebookController.pvcSize.replace(/\D/g, ''); + addClusterStorageModal.findPVStorageSizeValue().should('have.value', numericPvcSize); + addClusterStorageModal.findSubmitButton().click(); + clusterStorage.getClusterStorageRow(pvStorageName); + + // Edit the Cluster Storage, amend the name and update + cy.step('Edit the Cluster Storage and verify edits are successful'); + clusterStorage.findKebabToggle().click(); + clusterStorage.getClusterStorageRow(pvStorageName).findKebabAction('Edit storage').click(); + updateClusterStorageModal.findNameInput().clear(); + updateClusterStorageModal.findNameInput().type(pvStorageNameEdited); + updateClusterStorageModal.findSubmitButton().click(); + clusterStorage.getClusterStorageRow(pvStorageNameEdited); + + // Delete the Cluster Storage and confirm that the deletion was successful + cy.step('Delete the Cluster Storage and verify deletion'); + clusterStorage.findKebabToggle().click(); + clusterStorage.getClusterStorageRow(pvStorageName).findKebabAction('Delete storage').click(); + deleteModal.shouldBeOpen(); + deleteModal.findInput().type(pvStorageName); + deleteModal.findSubmitButton().should('be.enabled').click(); + clusterStorage.findEmptyState().should('exist'); + }, + ); +}); diff --git a/frontend/src/__tests__/cypress/cypress/types.ts b/frontend/src/__tests__/cypress/cypress/types.ts index 82fd267446..dc535c0e1b 100644 --- a/frontend/src/__tests__/cypress/cypress/types.ts +++ b/frontend/src/__tests__/cypress/cypress/types.ts @@ -133,6 +133,10 @@ export type DataScienceProjectData = { multiModelAdminName: string; modelOpenVinoExamplePath: string; projectDCResourceName: string; + projectPVStorageResourceName: string; + pvStorageName: string; + pvStorageDescription: string; + pvStorageNameEdited: string; }; export type NotebookImageData = {