Skip to content

Commit

Permalink
test: Cypress - Verify users can create a workbench and connect an ex…
Browse files Browse the repository at this point in the history
…istent PersistentVolume (#3511)

* test: Cypress - Verify users can create a workbench and connect an existent PersistentVolume

* lint fixes

* Add PVC size

* PR Fixes
  • Loading branch information
FedeAlonso authored Nov 26, 2024
1 parent 1fe5c73 commit 5627e0a
Show file tree
Hide file tree
Showing 7 changed files with 177 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# workbenches.cy.ts Test Data #
NAMESPACE: 'dsp-wb-test'
PVC_NAME: 'pvc-test-name'
PVC_DISPLAY_NAME: 'pvc-test-display-name'
PVC_SIZE: '10'
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: {{PVC_NAME}}
namespace: {{NAMESPACE}}
labels:
opendatahub.io/dashboard: 'true'
annotations:
openshift.io/description: ''
openshift.io/display-name: {{PVC_DISPLAY_NAME}}
finalizers:
- kubernetes.io/pvc-protection
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: {{PVC_SIZE}}Gi
storageClassName: standard-csi
volumeMode: Filesystem
status:
phase: Pending
16 changes: 14 additions & 2 deletions frontend/src/__tests__/cypress/cypress/pages/workbench.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,12 @@ class NotebookRow extends TableRow {
return this.find().findByTestId('notebook-route-link');
}

findHaveNotebookStatusText() {
return this.find().findByTestId('notebook-status-text');
findHaveNotebookStatusText(timeout = 10000) {
return this.find().findByTestId('notebook-status-text', { timeout });
}

expectStatusLabelToBe(statusValue: string, timeout?: number) {
this.findHaveNotebookStatusText(timeout).should('have.text', statusValue);
}

findNotebookStart() {
Expand Down Expand Up @@ -247,6 +251,10 @@ class CreateSpawnerPage {
return new StorageTable();
}

getNameInput() {
return cy.findByTestId('workbench-name');
}

private findPVSizeField() {
return cy.findByTestId('create-new-storage-size');
}
Expand All @@ -255,6 +263,10 @@ class CreateSpawnerPage {
return cy.findByTestId('value-unit-select');
}

findExsistingPersistentStorageRadio() {
return cy.findByTestId('persistent-existing-storage-type-radio');
}

selectExistingPersistentStorage(name: string) {
cy.findByTestId('persistent-storage-group')
.findByRole('button', { name: 'Typeahead menu toggle' })
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import type { PVCReplacements } from '~/__tests__/cypress/cypress/types';
import { projectDetails, projectListPage } from '~/__tests__/cypress/cypress/pages/projects';
import { workbenchPage, createSpawnerPage } from '~/__tests__/cypress/cypress/pages/workbench';
import { clusterStorage } from '~/__tests__/cypress/cypress/pages/clusterStorage';
import { HTPASSWD_CLUSTER_ADMIN_USER } from '~/__tests__/cypress/cypress/utils/e2eUsers';
import { loadPVCFixture } 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 { createPersistentVolumeClaim } from '~/__tests__/cypress/cypress/utils/oc_commands/presistentVolumeClaim';

describe('Workbench and PVSs tests', () => {
// let testData: PVCReplacements;
let projectName: string;
let PVCName: string;
let PVCDisplayName: string;
let PVCSize: string;

before(() => {
return loadPVCFixture('e2e/dataScienceProjects/testProjectWbPV.yaml')
.then((fixtureData: PVCReplacements) => {
projectName = fixtureData.NAMESPACE;
PVCName = fixtureData.PVC_NAME;
PVCDisplayName = fixtureData.PVC_DISPLAY_NAME;
PVCSize = fixtureData.PVC_SIZE;

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`);
const pvcReplacements: PVCReplacements = {
NAMESPACE: projectName,
PVC_NAME: PVCName,
PVC_DISPLAY_NAME: PVCDisplayName,
PVC_SIZE: PVCSize,
};
return createPersistentVolumeClaim(pvcReplacements);
})
.then((commandResult) => {
cy.log(`Persistent Volume Claim created: ${JSON.stringify(commandResult)}`);
});
});

after(() => {
// Delete provisioned Project
if (projectName) {
cy.log(`Deleting Project ${projectName} after the test has finished.`);
deleteOpenShiftProject(projectName);
}
});

it('Verify users can create a workbench and connect an existent PersistentVolume', () => {
const workbenchName = projectName.replace('dsp-', '');

// Authentication and navigation
cy.step('Log into the application');
cy.visitWithLogin('/', HTPASSWD_CLUSTER_ADMIN_USER);

cy.step(`Navigate to Workbenches tab of Project ${projectName}`);
projectListPage.navigate();
projectListPage.filterProjectByName(projectName);
projectListPage.findProjectLink(projectName).click();
projectDetails.findSectionTab('workbenches').click();

cy.step(`Create Workbench ${projectName} using storage ${PVCDisplayName}`);
workbenchPage.findCreateButton().click();
createSpawnerPage.getNameInput().fill(workbenchName);
createSpawnerPage.findNotebookImage('s2i-minimal-notebook').click();
createSpawnerPage.findExsistingPersistentStorageRadio().click();
createSpawnerPage.selectExistingPersistentStorage(PVCDisplayName);
createSpawnerPage.findSubmitButton().click();

cy.step(`Wait for Workbench ${workbenchName} to display a "Running" status`);
const notebookRow = workbenchPage.getNotebookRow(workbenchName);
notebookRow.expectStatusLabelToBe('Running', 120000);
notebookRow.shouldHaveNotebookImageName('Minimal Python');
notebookRow.shouldHaveContainerSize('Small');

cy.step(`Check the cluster storage ${PVCDisplayName} is now connected to ${workbenchName}`);
projectDetails.findSectionTab('cluster-storages').click();
const csRow = clusterStorage.getClusterStorageRow(PVCDisplayName);
csRow.findConnectedWorkbenches().should('have.text', workbenchName);
});
});
7 changes: 7 additions & 0 deletions frontend/src/__tests__/cypress/cypress/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,13 @@ export type SCReplacements = {
SC_IS_ENABLED: string;
};

export type PVCReplacements = {
NAMESPACE: string;
PVC_NAME: string;
PVC_DISPLAY_NAME: string;
PVC_SIZE: string;
};

export type CommandLineResult = {
code: number;
stdout: string;
Expand Down
14 changes: 13 additions & 1 deletion frontend/src/__tests__/cypress/cypress/utils/dataLoader.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import yaml from 'js-yaml';
import type { DataScienceProjectData, ResourcesData } from '~/__tests__/cypress/cypress/types';
import type {
DataScienceProjectData,
PVCReplacements,
ResourcesData,
} from '~/__tests__/cypress/cypress/types';

// Load fixture function that returns DataScienceProjectData
export const loadDSPFixture = (fixturePath: string): Cypress.Chainable<DataScienceProjectData> => {
Expand All @@ -16,3 +20,11 @@ export const loadResourcesFixture = (fixturePath: string): Cypress.Chainable<Res
return data;
});
};

export const loadPVCFixture = (fixturePath: string): Cypress.Chainable<PVCReplacements> => {
return cy.fixture(fixturePath, 'utf8').then((yamlContent: string) => {
const data = yaml.load(yamlContent) as PVCReplacements;

return data;
});
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import type { PVCReplacements, CommandLineResult } from '~/__tests__/cypress/cypress/types';
import { replacePlaceholdersInYaml } from '~/__tests__/cypress/cypress/utils/yaml_files';
import { applyOpenShiftYaml } from './baseCommands';

/**
* Create an Persistent Volume Claim based on the PVCReplacements config
* @param persistentVolumeClaimReplacements Dictionary with the config values
* Dict Structure:
* export type PVCReplacements = {
* NAMESPACE: string;
* PVC_NAME: string;
* PVC_DISPLAY_NAME: string;
* PVC_SIZE: string;
* };
* @param yamlFilePath
*/
export const createPersistentVolumeClaim = (
persistentVolumeClaimReplacements: PVCReplacements,
yamlFilePath = 'resources/yaml/persistentVolumeClaim.yaml',
): Cypress.Chainable<CommandLineResult> => {
return cy.fixture(yamlFilePath).then((yamlContent) => {
cy.log(yamlContent);
const modifiedYamlContent = replacePlaceholdersInYaml(
yamlContent,
persistentVolumeClaimReplacements,
);
return applyOpenShiftYaml(modifiedYamlContent);
});
};

0 comments on commit 5627e0a

Please sign in to comment.