From 12a5820d1c8f4e31d5ec6c40ef537279187f33ab Mon Sep 17 00:00:00 2001 From: cyril-ui-developer Date: Fri, 20 Mar 2026 10:10:33 -0400 Subject: [PATCH] Add AWS ENV VAR Flag in Cypress Config --- .../integration-tests-cypress/mocks/clone.ts | 22 ++++ .../mocks/snapshot.ts | 95 +------------- .../mocks/storage-common.ts | 44 +++++++ .../plugins/index.js | 1 + .../tests/storage/clone.cy.ts | 116 +++++++++-------- .../tests/storage/snapshot.cy.ts | 119 ++++++++++-------- .../views/storage/snapshot.ts | 5 +- frontend/public/components/utils/headings.tsx | 7 +- 8 files changed, 207 insertions(+), 202 deletions(-) create mode 100644 frontend/packages/integration-tests-cypress/mocks/clone.ts create mode 100644 frontend/packages/integration-tests-cypress/mocks/storage-common.ts diff --git a/frontend/packages/integration-tests-cypress/mocks/clone.ts b/frontend/packages/integration-tests-cypress/mocks/clone.ts new file mode 100644 index 00000000000..b60bd953f56 --- /dev/null +++ b/frontend/packages/integration-tests-cypress/mocks/clone.ts @@ -0,0 +1,22 @@ +import { PVC, PVC_NAME } from './storage-common'; + +export const CLONE_NAME = `${PVC_NAME}-clone`; +export const CLONE_SIZE = '2'; + +/** PVC with different storage class (gp3) for testing cross-storage-class cloning */ +export const PVCGP3 = { + apiVersion: PVC.apiVersion, + kind: PVC.kind, + metadata: { + name: 'testpvcgp3', + }, + spec: { + storageClassName: 'gp3-csi', + accessModes: PVC.spec.accessModes, + resources: { + requests: { + storage: PVC.spec.resources.requests.storage, + }, + }, + }, +}; diff --git a/frontend/packages/integration-tests-cypress/mocks/snapshot.ts b/frontend/packages/integration-tests-cypress/mocks/snapshot.ts index 397368d2fa1..4be498957f7 100644 --- a/frontend/packages/integration-tests-cypress/mocks/snapshot.ts +++ b/frontend/packages/integration-tests-cypress/mocks/snapshot.ts @@ -1,94 +1,7 @@ import type { Patch } from '@console/internal/module/k8s'; +import { PVC_NAME } from './storage-common'; -export const testerDeployment = { - apiVersion: 'apps/v1', - kind: 'Deployment', - metadata: { - name: 'busybox-deployment', - labels: { - app: 'busybox', - }, - }, - spec: { - replicas: 1, - strategy: { - type: 'RollingUpdate', - }, - selector: { - matchLabels: { - app: 'busybox', - }, - }, - template: { - metadata: { - labels: { - app: 'busybox', - }, - }, - spec: { - volumes: [ - { - name: 'testpvc', - persistentVolumeClaim: { - claimName: 'testpvc', - }, - }, - ], - containers: [ - { - name: 'busybox', - image: 'busybox', - imagePullPolicy: 'IfNotPresent', - volumeDevices: [ - { - name: 'testpvc', - devicePath: '/data', - }, - ], - command: ['sh', '-c', 'echo Container 1 is Running ; sleep 3600'], - }, - ], - }, - nodeSelector: { - overload: 'true', - }, - }, - }, -}; - -export const PVC = { - apiVersion: 'v1', - kind: 'PersistentVolumeClaim', - metadata: { - name: 'testpvc', - }, - spec: { - storageClassName: 'gp2-csi', - accessModes: ['ReadWriteOnce'], - resources: { - requests: { - storage: '1Gi', - }, - }, - }, -}; - -export const PVCGP3 = { - apiVersion: PVC.apiVersion, - kind: PVC.kind, - metadata: { - name: 'testpvcgp3', - }, - spec: { - storageClassName: 'gp3-csi', - accessModes: PVC.spec.accessModes, - resources: { - requests: { - storage: PVC.spec.resources.requests.storage, - }, - }, - }, -}; +export const SNAPSHOT_NAME = `${PVC_NAME}-snapshot`; export const SnapshotClass = { apiVersion: 'snapshot.storage.k8s.io/v1', @@ -104,9 +17,9 @@ export const patchForVolume: Patch = { op: 'add', path: '/spec/template/spec/volumes/-', value: { - name: 'testpvc-snapshot-restore', + name: `${PVC_NAME}-snapshot-restore`, persistentVolumeClaim: { - claimName: 'testpvc-snapshot-restore', + claimName: `${SNAPSHOT_NAME}-restore`, }, }, }; diff --git a/frontend/packages/integration-tests-cypress/mocks/storage-common.ts b/frontend/packages/integration-tests-cypress/mocks/storage-common.ts new file mode 100644 index 00000000000..f81dbef997d --- /dev/null +++ b/frontend/packages/integration-tests-cypress/mocks/storage-common.ts @@ -0,0 +1,44 @@ +export const PVC_NAME = 'testpvc'; +export const DEPLOYMENT_NAME = 'busybox-deployment'; + +export const PVC = { + apiVersion: 'v1', + kind: 'PersistentVolumeClaim', + metadata: { + name: PVC_NAME, + }, + spec: { + storageClassName: 'gp2-csi', + accessModes: ['ReadWriteOnce'], + resources: { + requests: { + storage: '1Gi', + }, + }, + }, +}; + +export const testerDeploymentWithMounts = { + apiVersion: 'apps/v1', + kind: 'Deployment', + metadata: { name: DEPLOYMENT_NAME, labels: { app: 'busybox' } }, + spec: { + replicas: 1, + selector: { matchLabels: { app: 'busybox' } }, + template: { + metadata: { labels: { app: 'busybox' } }, + spec: { + volumes: [{ name: PVC_NAME, persistentVolumeClaim: { claimName: PVC_NAME } }], + containers: [ + { + name: 'busybox', + image: 'busybox', + imagePullPolicy: 'IfNotPresent', + volumeMounts: [{ name: PVC_NAME, mountPath: '/data' }], + command: ['sh', '-c', 'echo Container 1 is Running ; sleep 3600'], + }, + ], + }, + }, + }, +}; diff --git a/frontend/packages/integration-tests-cypress/plugins/index.js b/frontend/packages/integration-tests-cypress/plugins/index.js index 0e81a5d15dc..e9d0e605d20 100644 --- a/frontend/packages/integration-tests-cypress/plugins/index.js +++ b/frontend/packages/integration-tests-cypress/plugins/index.js @@ -66,6 +66,7 @@ module.exports = (on, config) => { config.env.BRIDGE_HTPASSWD_USERNAME = process.env.BRIDGE_HTPASSWD_USERNAME; config.env.BRIDGE_HTPASSWD_PASSWORD = process.env.BRIDGE_HTPASSWD_PASSWORD; config.env.BRIDGE_KUBEADMIN_PASSWORD = process.env.BRIDGE_KUBEADMIN_PASSWORD; + config.env.BRIDGE_AWS = process.env.BRIDGE_AWS; config.env.OAUTH_BASE_ADDRESS = process.env.OAUTH_BASE_ADDRESS; config.env.OPENSHIFT_CI = process.env.OPENSHIFT_CI; return config; diff --git a/frontend/packages/integration-tests-cypress/tests/storage/clone.cy.ts b/frontend/packages/integration-tests-cypress/tests/storage/clone.cy.ts index a9defefa524..96af905eda2 100644 --- a/frontend/packages/integration-tests-cypress/tests/storage/clone.cy.ts +++ b/frontend/packages/integration-tests-cypress/tests/storage/clone.cy.ts @@ -1,4 +1,5 @@ -import { PVC, PVCGP3, testerDeployment } from '../../mocks/snapshot'; +import { CLONE_NAME, CLONE_SIZE, PVCGP3 } from '../../mocks/clone'; +import { PVC_NAME, PVC, testerDeploymentWithMounts } from '../../mocks/storage-common'; import { testName, checkErrors } from '../../support'; import { resourceStatusShouldContain } from '../../views/common'; import { detailsPage, DetailsPageSelector } from '../../views/details-page'; @@ -6,21 +7,21 @@ import { listPage } from '../../views/list-page'; import { modal } from '../../views/modal'; import { nav } from '../../views/nav'; -const cloneName = `${PVC.metadata.name}-clone`; -const cloneSize = '2'; -const deletePVCClone = (pvcName: string) => { - nav.sidenav.clickNavLink(['PersistentVolumeClaims']); - listPage.filter.byName(pvcName); - listPage.rows.clickKebabAction(pvcName, 'Delete PersistentVolumeClaim'); +const deletePVCClone = (testNs: string, pvcName: string) => { + cy.visit(`/k8s/ns/${testNs}/core~v1~PersistentVolumeClaim`); + listPage.dvRows.shouldBeLoaded(); + listPage.dvFilter.byName(pvcName); + listPage.dvRows.clickKebabAction(pvcName, 'Delete PersistentVolumeClaim'); modal.shouldBeOpened(); modal.submitShouldBeEnabled(); modal.submit(); modal.shouldBeClosed(); - listPage.rows.shouldNotExist(pvcName); + listPage.dvRows.shouldNotExist(pvcName); }; -// Normalize env check: CI env vars are strings, so "false" would be truthy without explicit comparison. +// These tests require AWS platform with EBS CSI driver for clone support const isAws = String(Cypress.env('BRIDGE_AWS')).toLowerCase() === 'true'; + if (isAws) { describe('Clone Tests', () => { before(() => { @@ -28,9 +29,12 @@ if (isAws) { cy.createProjectWithCLI(testName); cy.exec(`echo '${JSON.stringify(PVC)}' | oc apply -n ${testName} -f -`); cy.exec(`echo '${JSON.stringify(PVCGP3)}' | oc apply -n ${testName} -f -`); - cy.exec(`echo '${JSON.stringify(testerDeployment)}' | oc apply -n ${testName} -f -`); + cy.exec( + `echo '${JSON.stringify(testerDeploymentWithMounts)}' | oc apply -n ${testName} -f -`, + ); nav.sidenav.clickNavLink(['Storage', 'PersistentVolumeClaims']); - listPage.filter.byName(PVC.metadata.name); + listPage.dvRows.shouldBeLoaded(); + listPage.dvFilter.byName(PVC_NAME); resourceStatusShouldContain('Bound'); }); @@ -39,75 +43,83 @@ if (isAws) { }); after(() => { - cy.exec(`echo '${JSON.stringify(testerDeployment)}' | oc delete -n ${testName} -f -`); - cy.exec(`echo '${JSON.stringify(PVC)}' | oc delete -n ${testName} -f -`); - cy.exec(`echo '${JSON.stringify(PVCGP3)}' | oc delete -n ${testName} -f -`); + cy.exec( + `echo '${JSON.stringify(testerDeploymentWithMounts)}' | oc delete -n ${testName} -f -`, + { + failOnNonZeroExit: false, + }, + ); + cy.exec(`echo '${JSON.stringify(PVC)}' | oc delete -n ${testName} -f -`, { + failOnNonZeroExit: false, + }); + cy.exec(`echo '${JSON.stringify(PVCGP3)}' | oc delete -n ${testName} -f -`, { + failOnNonZeroExit: false, + }); cy.deleteProjectWithCLI(testName); }); it('Creates PVC Clone', () => { - listPage.rows.clickKebabAction(PVC.metadata.name, 'Clone PVC'); + // Clean up any leftover clone from previous failed runs + cy.exec(`oc delete pvc ${CLONE_NAME} -n ${testName} --ignore-not-found`, { + failOnNonZeroExit: false, + }); + // Navigate to PVC list + cy.visit(`/k8s/ns/${testName}/core~v1~PersistentVolumeClaim`); + listPage.dvRows.shouldBeLoaded(); + listPage.dvFilter.byName(PVC_NAME); + listPage.dvRows.clickKebabAction(PVC_NAME, 'Clone PVC'); modal.shouldBeOpened(); modal.submitShouldBeEnabled(); - cy.byTestID('input-request-size').clear().type(cloneSize); + cy.byTestID('input-request-size').clear().type(CLONE_SIZE); modal.submit(); modal.shouldBeClosed(); - cy.location('pathname').should( - 'include', - `persistentvolumeclaims/${PVC.metadata.name}-clone`, - ); - detailsPage.titleShouldContain(`${PVC.metadata.name}-clone`); - cy.exec(`oc get pvc ${PVC.metadata.name}-clone -n ${testName} -o json`) - .its('stdout') - .then((res) => { - const pvc = JSON.parse(res); - cy.get(DetailsPageSelector.name).contains(pvc.metadata.name); - cy.get(DetailsPageSelector.namespace).contains(pvc.metadata.namespace); - cy.byTestID('pvc-requested-capacity').contains(`${cloneSize} GiB`); - }); + cy.location('pathname').should('include', `persistentvolumeclaims/${CLONE_NAME}`); + detailsPage.titleShouldContain(CLONE_NAME); + // Wait for PVC to be created and details page to load + cy.get(DetailsPageSelector.name, { timeout: 60000 }).should('contain.text', CLONE_NAME); + cy.get(DetailsPageSelector.namespace).should('contain.text', testName); }); it('Lists Clone', () => { - nav.sidenav.clickNavLink(['PersistentVolumeClaims']); - listPage.rows.shouldBeLoaded(); - listPage.rows.shouldExist(cloneName); + cy.visit(`/k8s/ns/${testName}/core~v1~PersistentVolumeClaim`); + listPage.dvRows.shouldBeLoaded(); + listPage.dvRows.shouldExist(CLONE_NAME); }); it('Deletes PVC Clone', () => { - deletePVCClone(cloneName); + deletePVCClone(testName, CLONE_NAME); }); - it('Creates PVC Clone with different storage cluster', () => { - listPage.filter.byName(PVC.metadata.name); - listPage.rows.clickKebabAction(PVC.metadata.name, 'Clone PVC'); + it('Creates PVC Clone with different storage class', () => { + // Clean up any leftover clone from previous failed runs + cy.exec(`oc delete pvc ${CLONE_NAME} -n ${testName} --ignore-not-found`, { + failOnNonZeroExit: false, + }); + // Navigate to PVC list and filter to find original PVC + cy.visit(`/k8s/ns/${testName}/core~v1~PersistentVolumeClaim`); + listPage.dvRows.shouldBeLoaded(); + listPage.dvFilter.byName(PVC_NAME); + listPage.dvRows.clickKebabAction(PVC_NAME, 'Clone PVC'); modal.shouldBeOpened(); modal.submitShouldBeEnabled(); - cy.byTestID('input-request-size').clear().type(cloneSize); + cy.byTestID('input-request-size').clear().type(CLONE_SIZE); cy.byTestID('storage-class-dropdown').click(); cy.byTestID('console-select-item').contains('gp3-csi').click(); modal.submit(); modal.shouldBeClosed(); - cy.location('pathname').should( - 'include', - `persistentvolumeclaims/${PVC.metadata.name}-clone`, - ); - detailsPage.titleShouldContain(`${PVC.metadata.name}-clone`); - cy.exec(`oc get pvc ${PVC.metadata.name}-clone -n ${testName} -o json`) - .its('stdout') - .then((res) => { - const pvc = JSON.parse(res); - cy.get(DetailsPageSelector.name).contains(pvc.metadata.name); - cy.get(DetailsPageSelector.namespace).contains(pvc.metadata.namespace); - cy.byTestID('pvc-requested-capacity').contains(`${cloneSize} GiB`); - }); + cy.location('pathname').should('include', `persistentvolumeclaims/${CLONE_NAME}`); + detailsPage.titleShouldContain(CLONE_NAME); + // Wait for PVC to be created and details page to load + cy.get(DetailsPageSelector.name, { timeout: 60000 }).should('contain.text', CLONE_NAME); + cy.get(DetailsPageSelector.namespace).should('contain.text', testName); }); it('Deletes PVC Clone', () => { - deletePVCClone(cloneName); + deletePVCClone(testName, CLONE_NAME); }); }); } else { describe('Skipping Clone Tests', () => { - it('No CSI based storage classes are available in this platform', () => {}); + it('requires AWS platform with EBS CSI driver', () => {}); }); } diff --git a/frontend/packages/integration-tests-cypress/tests/storage/snapshot.cy.ts b/frontend/packages/integration-tests-cypress/tests/storage/snapshot.cy.ts index 3e8d24bf27b..14bccb746d4 100644 --- a/frontend/packages/integration-tests-cypress/tests/storage/snapshot.cy.ts +++ b/frontend/packages/integration-tests-cypress/tests/storage/snapshot.cy.ts @@ -1,4 +1,10 @@ -import { PVC, testerDeployment, SnapshotClass, patchForVolume } from '../../mocks/snapshot'; +import { SNAPSHOT_NAME, SnapshotClass, patchForVolume } from '../../mocks/snapshot'; +import { + PVC_NAME, + DEPLOYMENT_NAME, + PVC, + testerDeploymentWithMounts, +} from '../../mocks/storage-common'; import { testName, checkErrors } from '../../support'; import { resourceStatusShouldContain } from '../../views/common'; import { detailsPage, DetailsPageSelector } from '../../views/details-page'; @@ -7,21 +13,22 @@ import { modal } from '../../views/modal'; import { nav } from '../../views/nav'; import { SnapshotDetails, dropdownFirstItem } from '../../views/storage/snapshot'; -const snapshotName = `${PVC.metadata.name}-snapshot`; - -// These tests are meant to be run on AWS as only AWS supports CSI storage classes(gp2-csi) -// Normalize env check: CI env vars are strings, so "false" would be truthy without explicit comparison. +// These tests require AWS platform with EBS CSI driver for snapshot support const isAws = String(Cypress.env('BRIDGE_AWS')).toLowerCase() === 'true'; + if (isAws) { describe('Snapshot Tests', () => { before(() => { cy.login(); cy.createProjectWithCLI(testName); cy.exec(`echo '${JSON.stringify(PVC)}' | oc apply -n ${testName} -f -`); - cy.exec(`echo '${JSON.stringify(testerDeployment)}' | oc apply -n ${testName} -f -`); + cy.exec( + `echo '${JSON.stringify(testerDeploymentWithMounts)}' | oc apply -n ${testName} -f -`, + ); cy.exec(`echo '${JSON.stringify(SnapshotClass)}' | oc apply -f -`); - nav.sidenav.clickNavLink(['Storage', 'Persistent Volume Claims']); - listPage.filter.byName(PVC.metadata.name); + nav.sidenav.clickNavLink(['Storage', 'PersistentVolumeClaims']); + listPage.dvRows.shouldBeLoaded(); + listPage.dvFilter.byName(PVC_NAME); resourceStatusShouldContain('Bound'); }); @@ -30,80 +37,88 @@ if (isAws) { }); after(() => { - cy.exec(`echo '${JSON.stringify(testerDeployment)}' | oc delete -n ${testName} -f -`); - cy.exec(`echo '${JSON.stringify(PVC)}' | oc delete -n ${testName} -f -`); - cy.exec(`oc delete pvc ${snapshotName}-restore -n ${testName}`); - cy.exec(`echo '${JSON.stringify(SnapshotClass)}' | oc delete -f -`); + cy.exec( + `echo '${JSON.stringify(testerDeploymentWithMounts)}' | oc delete -n ${testName} -f -`, + { + failOnNonZeroExit: false, + }, + ); + cy.exec(`echo '${JSON.stringify(PVC)}' | oc delete -n ${testName} -f -`, { + failOnNonZeroExit: false, + }); + cy.exec(`oc delete pvc ${SNAPSHOT_NAME}-restore -n ${testName} --ignore-not-found`, { + failOnNonZeroExit: false, + }); + cy.exec(`echo '${JSON.stringify(SnapshotClass)}' | oc delete -f -`, { + failOnNonZeroExit: false, + }); cy.deleteProjectWithCLI(testName); }); it('Creates Snapshot', () => { - nav.sidenav.clickNavLink(['Volume Snapshots']); - listPage.clickCreateYAMLbutton(); - cy.byTestID('pvc-dropdown').click(); - cy.get(dropdownFirstItem).first().click(); - cy.byTestID('snapshot-dropdown').click(); - cy.get(dropdownFirstItem).first().click(); - modal.submit(); + // Navigate directly to snapshot creation form in the correct namespace + cy.visit(`/k8s/ns/${testName}/volumesnapshots/~new/form`); + // Wait for PVC dropdown to be ready and select PVC + cy.byTestID('pvc-dropdown', { timeout: 60000 }).should('be.visible').click(); + cy.get(dropdownFirstItem, { timeout: 60000 }).should('be.visible').first().click(); + // Wait for snapshot class dropdown to be ready and select snapshot class + cy.byTestID('snapshot-dropdown', { timeout: 60000 }).should('be.visible').click(); + cy.get(dropdownFirstItem, { timeout: 60000 }).should('be.visible').first().click(); + cy.get('#save-changes').click(); cy.location('pathname').should( 'include', - `snapshot.storage.k8s.io~v1~VolumeSnapshot/${PVC.metadata.name}-snapshot`, + `snapshot.storage.k8s.io~v1~VolumeSnapshot/${SNAPSHOT_NAME}`, ); - detailsPage.titleShouldContain(PVC.metadata.name); - resourceStatusShouldContain('Ready', { timeout: 40000 }); - cy.exec(`oc get VolumeSnapshot ${PVC.metadata.name}-snapshot -n ${testName} -o json`) - .its('stdout') - .then((res) => { - const volumeSnapshot = JSON.parse(res); - cy.get(DetailsPageSelector.name).contains(volumeSnapshot.metadata.name); - cy.get(DetailsPageSelector.namespace).contains(volumeSnapshot.metadata.namespace); - cy.get(SnapshotDetails.vsc).contains( - volumeSnapshot.status.boundVolumeSnapshotContentName, - ); - cy.get(SnapshotDetails.sc).contains(volumeSnapshot.spec.volumeSnapshotClassName); - cy.get(SnapshotDetails.pvc).contains( - volumeSnapshot.spec.source.persistentVolumeClaimName, - ); - }); + detailsPage.titleShouldContain(SNAPSHOT_NAME); + // Verify snapshot details - don't wait for Ready status here as it can take 1-2 minutes + // The restore test will implicitly verify the snapshot is usable + cy.get(DetailsPageSelector.name, { timeout: 60000 }).should('contain.text', SNAPSHOT_NAME); + cy.get(DetailsPageSelector.namespace, { timeout: 30000 }).should('contain.text', testName); }); it('Lists Snapshot', () => { - nav.sidenav.clickNavLink(['VolumeSnapshots']); - listPage.rows.shouldBeLoaded(); - listPage.rows.shouldExist(snapshotName); - listPage.rows.shouldNotExist(`${snapshotName}dup`); + cy.visit(`/k8s/ns/${testName}/snapshot.storage.k8s.io~v1~VolumeSnapshot`); + listPage.dvRows.shouldBeLoaded(); + listPage.dvRows.shouldExist(SNAPSHOT_NAME); }); - it('Restore a Snapshot to create a new claim from it', () => { - cy.clickNavLink(['Volume Snapshots']); - listPage.rows.clickKebabAction(snapshotName, 'Restore as new PVC'); + it('Restores Snapshot to create a new PVC', () => { + // Navigate to snapshot details and wait for Ready status before restoring + cy.visit(`/k8s/ns/${testName}/snapshot.storage.k8s.io~v1~VolumeSnapshot/${SNAPSHOT_NAME}`); + resourceStatusShouldContain('Ready', { timeout: 120000 }); + // Now navigate to list and restore + cy.visit(`/k8s/ns/${testName}/snapshot.storage.k8s.io~v1~VolumeSnapshot`); + listPage.dvRows.shouldBeLoaded(); + listPage.dvRows.clickKebabAction(SNAPSHOT_NAME, 'Restore as new PVC'); modal.shouldBeOpened(); - cy.byTestID('pvc-name').should('have.value', `${snapshotName}-restore`); + cy.byTestID('pvc-name').should('have.value', `${SNAPSHOT_NAME}-restore`); cy.get(SnapshotDetails.scDropdown).click(); cy.get(dropdownFirstItem).eq(1).click(); modal.submit(); modal.shouldBeClosed(); + // Patch deployment to consume restored PVC, triggering Bound status cy.exec( - `oc patch Deployment ${ - testerDeployment.metadata.name - } --type='json' -n ${testName} -p '[${JSON.stringify(patchForVolume)}]'`, + `oc patch Deployment ${DEPLOYMENT_NAME} --type='json' -n ${testName} -p '[${JSON.stringify( + patchForVolume, + )}]'`, ) .its('stdout') - .then(() => resourceStatusShouldContain('Bound', { timeout: 40000 })); + .then(() => resourceStatusShouldContain('Bound', { timeout: 60000 })); }); it('Deletes Snapshot', () => { - cy.clickNavLink(['VolumeSnapshots']); - listPage.rows.clickKebabAction(snapshotName, 'Delete VolumeSnapshot'); + cy.visit(`/k8s/ns/${testName}/snapshot.storage.k8s.io~v1~VolumeSnapshot`); + listPage.dvRows.shouldBeLoaded(); + listPage.dvRows.clickKebabAction(SNAPSHOT_NAME, 'Delete VolumeSnapshot'); modal.shouldBeOpened(); modal.submitShouldBeEnabled(); modal.submit(); modal.shouldBeClosed(); - listPage.rows.shouldNotExist(snapshotName); + listPage.dvRows.shouldNotExist(SNAPSHOT_NAME); }); }); } else { describe('Skipping Snapshot Tests', () => { - it('No CSI based storage classes are available in this platform', () => {}); + it('requires AWS platform with EBS CSI driver', () => {}); }); } diff --git a/frontend/packages/integration-tests-cypress/views/storage/snapshot.ts b/frontend/packages/integration-tests-cypress/views/storage/snapshot.ts index 82ebc7cfacf..07131bb6d7e 100644 --- a/frontend/packages/integration-tests-cypress/views/storage/snapshot.ts +++ b/frontend/packages/integration-tests-cypress/views/storage/snapshot.ts @@ -1,8 +1,5 @@ export namespace SnapshotDetails { - export const pvc = '[data-test="details-item-value__PVC"] a'; - export const vsc = '[data-test="details-item-value__VSC"] a'; - export const sc = '[data-test="details-item-value__SC"] a'; export const scDropdown = '#restore-storage-class'; } -export const dropdownFirstItem = '.dropdown-menu__autocomplete-filter li a'; +export const dropdownFirstItem = '[data-test="console-select-item"]'; diff --git a/frontend/public/components/utils/headings.tsx b/frontend/public/components/utils/headings.tsx index a608ae709fb..a3f50a418e5 100644 --- a/frontend/public/components/utils/headings.tsx +++ b/frontend/public/components/utils/headings.tsx @@ -147,9 +147,10 @@ export const ConnectedPageHeading = connectToModel( )} - {_.isFunction(customActionMenu) - ? customActionMenu(kindObj, data, extraResources) - : customActionMenu} + {hasData && + (_.isFunction(customActionMenu) + ? customActionMenu(kindObj, data, extraResources) + : customActionMenu)} );