From 3e41a64f80632e91dae1f00ba011075199e08b15 Mon Sep 17 00:00:00 2001 From: Neil MacDougall Date: Mon, 1 Jul 2024 17:20:28 +0100 Subject: [PATCH] Fix bug with dialog for pod deletion (#11307) * Fix bug with dialog for pod deletion * Fix merge issues * Remove deletion hook, as the test actually deletes the pod --- .../e2e/po/components/sortable-table.po.ts | 12 +++- .../po/pages/explorer/workloads-pods.po.ts | 8 +++ cypress/e2e/po/prompts/promptRemove.po.ts | 4 ++ .../pages/explorer/workloads/pods.spec.ts | 57 ++++++++++++++++++- shell/components/PromptRemove.vue | 1 + shell/promptRemove/pod.vue | 22 ++++--- 6 files changed, 93 insertions(+), 11 deletions(-) diff --git a/cypress/e2e/po/components/sortable-table.po.ts b/cypress/e2e/po/components/sortable-table.po.ts index 8aed12da636..6458b1219db 100644 --- a/cypress/e2e/po/components/sortable-table.po.ts +++ b/cypress/e2e/po/components/sortable-table.po.ts @@ -74,6 +74,12 @@ export default class SortableTablePo extends ComponentPo { .type(searchText); } + resetFilter() { + return cy.get('[data-testid="search-box-filter-row"] input') + .focus() + .clear(); + } + // // sortable-table // @@ -167,12 +173,12 @@ export default class SortableTablePo extends ComponentPo { * @param expected number of rows shown * @returns */ - checkRowCount(isEmpty: boolean, expected: number) { + checkRowCount(isEmpty: boolean, expected: number, hasFilter = false) { return this.rowElements().should((el) => { if (isEmpty) { expect(el).to.have.length(expected); - expect(el).to.have.text('There are no rows to show.'); - expect(el).to.have.attr('class', 'no-rows'); + expect(el).to.have.text(hasFilter ? 'There are no rows which match your search query.' : 'There are no rows to show.'); + expect(el).to.have.attr('class', hasFilter ? 'no-results' : 'no-rows'); } else { expect(el).to.have.length(expected); expect(el).to.have.attr('data-node-id'); diff --git a/cypress/e2e/po/pages/explorer/workloads-pods.po.ts b/cypress/e2e/po/pages/explorer/workloads-pods.po.ts index a185990b758..4f2fb95fd73 100644 --- a/cypress/e2e/po/pages/explorer/workloads-pods.po.ts +++ b/cypress/e2e/po/pages/explorer/workloads-pods.po.ts @@ -2,6 +2,9 @@ import PagePo from '@/cypress/e2e/po/pages/page.po'; import PodsListPo from '@/cypress/e2e/po/lists/pods-list.po'; import BurgerMenuPo from '@/cypress/e2e/po/side-bars/burger-side-menu.po'; import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po'; + +import { WorkloadsCreatePageBasePo } from '@/cypress/e2e/po/pages/explorer/workloads/workloads.po'; + export class WorkloadsPodsListPagePo extends PagePo { private static createPath(clusterId: string) { return `/c/${ clusterId }/explorer/pod`; @@ -64,3 +67,8 @@ export class WorkLoadsPodDetailsPagePo extends PagePo { WorkLoadsPodDetailsPagePo.url = WorkLoadsPodDetailsPagePo.createPath(podId, clusterId, namespaceId, queryParams); } } +export class WorkloadsPodsCreatePagePo extends WorkloadsCreatePageBasePo { + constructor(protected clusterId: string = 'local', workloadType = 'pod', queryParams?: Record) { + super(clusterId, workloadType, queryParams); + } +} diff --git a/cypress/e2e/po/prompts/promptRemove.po.ts b/cypress/e2e/po/prompts/promptRemove.po.ts index 6d81adf634a..755cbe92bf1 100644 --- a/cypress/e2e/po/prompts/promptRemove.po.ts +++ b/cypress/e2e/po/prompts/promptRemove.po.ts @@ -22,6 +22,10 @@ export default class PromptRemove extends ComponentPo { return this.self().getId('prompt-remove-confirm-button').click(); } + cancel() { + return this.self().get('.btn.role-secondary').click(); + } + // Get the warning message warning() { return this.self().get('[warning] .text-warning'); diff --git a/cypress/e2e/tests/pages/explorer/workloads/pods.spec.ts b/cypress/e2e/tests/pages/explorer/workloads/pods.spec.ts index dcdbeef9921..67b4cab3a61 100644 --- a/cypress/e2e/tests/pages/explorer/workloads/pods.spec.ts +++ b/cypress/e2e/tests/pages/explorer/workloads/pods.spec.ts @@ -1,6 +1,7 @@ -import { WorkloadsPodsListPagePo, WorkLoadsPodDetailsPagePo } from '@/cypress/e2e/po/pages/explorer/workloads-pods.po'; +import { WorkloadsPodsListPagePo, WorkLoadsPodDetailsPagePo, WorkloadsPodsCreatePagePo } from '@/cypress/e2e/po/pages/explorer/workloads-pods.po'; import { createPodBlueprint, clonePodBlueprint } from '@/cypress/e2e/blueprints/explorer/workload-pods'; import PodPo from '@/cypress/e2e/po/components/workloads/pod.po'; +import PromptRemove from '@/cypress/e2e/po/prompts/promptRemove.po'; import HomePagePo from '@/cypress/e2e/po/pages/home.po'; import { generatePodsDataSmall } from '@/cypress/e2e/blueprints/explorer/workloads/pods/pods-get'; @@ -241,6 +242,60 @@ describe('Pods', { testIsolation: 'off', tags: ['@explorer', '@adminUser'] }, () }); }); + describe('should delete pod', () => { + const podName = `test-pod-${ Date.now() }`; + + beforeEach(() => { + workloadsPodPage.goTo(); + }); + + it('dialog should open/close as expected', () => { + const podCreatePage = new WorkloadsPodsCreatePagePo('local'); + + podCreatePage.goTo(); + + podCreatePage.createWithUI(podName, 'nginx', 'default'); + + // Should be on the list view + const podsListPage = new WorkloadsPodsListPagePo('local'); + + // Filter the list to just show the newly created pod + podsListPage.list().resourceTable().sortableTable().filter(podName); + podsListPage.list().resourceTable().sortableTable().checkRowCount(false, 1); + + // Open action menu and delete for the first item + podsListPage.list().resourceTable().sortableTable().rowActionMenuOpen(podName) + .getMenuItem('Delete') + .click(); + + let dialog = new PromptRemove(); + + dialog.checkExists(); + dialog.checkVisible(); + + dialog.cancel(); + dialog.checkNotExists(); + + podsListPage.list().resourceTable().sortableTable().checkRowCount(false, 1); + + // Open action menu and delete for the first item + podsListPage.list().resourceTable().sortableTable().rowActionMenuOpen(podName) + .getMenuItem('Delete') + .click(); + + dialog = new PromptRemove(); + + dialog.checkExists(); + dialog.checkVisible(); + dialog.remove(); + dialog.checkNotExists(); + + podsListPage.list().resourceTable().sortableTable().checkRowCount(true, 1, true); + + podsListPage.list().resourceTable().sortableTable().resetFilter(); + }); + }); + after(() => { // delete namespace (this will also delete all pods in it) cy.deleteRancherResource('v1', 'namespaces', nsName); diff --git a/shell/components/PromptRemove.vue b/shell/components/PromptRemove.vue index b8248702649..d48c0a3f8d8 100644 --- a/shell/components/PromptRemove.vue +++ b/shell/components/PromptRemove.vue @@ -376,6 +376,7 @@ export default { :value="toRemove" :names="names" :type="type" + :done-location="doneLocation" @errors="e => error = e" @done="done" /> diff --git a/shell/promptRemove/pod.vue b/shell/promptRemove/pod.vue index 22656084b50..3f80f5802b1 100644 --- a/shell/promptRemove/pod.vue +++ b/shell/promptRemove/pod.vue @@ -30,6 +30,16 @@ export default { type: { type: String, required: true + }, + + close: { + type: Function, + required: true + }, + + doneLocation: { + type: Object, + default: () => {} } }, @@ -69,23 +79,21 @@ export default { methods: { async remove(confirm) { - const parentComponent = this.$parent.$parent.$parent; - let goTo; - if (parentComponent.doneLocation) { + if (this.doneLocation) { // doneLocation will recompute to undefined when delete request completes - goTo = { ...parentComponent.doneLocation }; + goTo = { ...this.doneLocation }; } try { await Promise.all(this.value.map((resource) => this.removePod(resource))); if ( goTo && !isEmpty(goTo) ) { - parentComponent.currentRouter.push(goTo); + this.value?.[0]?.currentRouter().push(goTo); } - parentComponent.close(); + this.close(); } catch (err) { - parentComponent.error = err; + this.$emit('errors', err); confirm(false); } },