From 343ab9603016422dcd7dc9c19bb0cdd1b10f9af0 Mon Sep 17 00:00:00 2001 From: kay delaney <45561153+kaydelaney@users.noreply.github.com> Date: Wed, 7 May 2025 12:31:53 +0100 Subject: [PATCH] Dashboards/E2E: Add tests for removing panel(s) (#104998) * Dashboards/E2E: Add tests for removing panel(s) --- .../dashboards-remove-panel.spec.ts | 37 +++++++++++++++++++ e2e/utils/flows/scenes/index.ts | 2 + e2e/utils/flows/scenes/removePanel.ts | 17 +++++++++ e2e/utils/flows/scenes/selectPanel.ts | 11 ++++++ e2e/utils/flows/scenes/toggleEditMode.ts | 5 +++ .../src/selectors/components.ts | 8 ++++ .../PanelChrome/PanelChrome.test.tsx | 8 ++-- .../components/PanelChrome/PanelChrome.tsx | 2 +- .../edit-pane/EditPaneHeader.tsx | 2 + 9 files changed, 87 insertions(+), 5 deletions(-) create mode 100644 e2e/dashboards-edit-v2-suite/dashboards-remove-panel.spec.ts create mode 100644 e2e/utils/flows/scenes/removePanel.ts create mode 100644 e2e/utils/flows/scenes/selectPanel.ts create mode 100644 e2e/utils/flows/scenes/toggleEditMode.ts diff --git a/e2e/dashboards-edit-v2-suite/dashboards-remove-panel.spec.ts b/e2e/dashboards-edit-v2-suite/dashboards-remove-panel.spec.ts new file mode 100644 index 00000000000..6bdd01601d4 --- /dev/null +++ b/e2e/dashboards-edit-v2-suite/dashboards-remove-panel.spec.ts @@ -0,0 +1,37 @@ +import { e2e } from '../utils'; + +const PAGE_UNDER_TEST = 'edediimbjhdz4b/a-tall-dashboard'; + +describe('Dashboard panels', () => { + beforeEach(() => { + e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD')); + }); + + it('can remove a panel', () => { + e2e.pages.Dashboards.visit(); + e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?orgId=1` }); + + e2e.flows.scenes.toggleEditMode(); + + e2e.flows.scenes.removePanels(/^Panel #1$/); + + // Check that panel has been deleted + e2e.components.Panels.Panel.headerContainer() + .contains(/^Panel #1$/) + .should('not.exist'); + }); + + it('can remove several panels at once', () => { + e2e.pages.Dashboards.visit(); + e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?orgId=1` }); + + e2e.flows.scenes.toggleEditMode(); + + e2e.flows.scenes.removePanels(/^Panel #1$/, /^Panel #2$/, /^Panel #3$/); + + // Check that panels have been deleted + e2e.components.Panels.Panel.headerContainer() + .contains(/^Panel #[123]$/) + .should('not.exist'); + }); +}); diff --git a/e2e/utils/flows/scenes/index.ts b/e2e/utils/flows/scenes/index.ts index 70488d43dc5..fa385607cc8 100644 --- a/e2e/utils/flows/scenes/index.ts +++ b/e2e/utils/flows/scenes/index.ts @@ -1,2 +1,4 @@ export * from './addPanel'; export * from './configurePanel'; +export * from './removePanel'; +export * from './toggleEditMode'; diff --git a/e2e/utils/flows/scenes/removePanel.ts b/e2e/utils/flows/scenes/removePanel.ts new file mode 100644 index 00000000000..032052f4b82 --- /dev/null +++ b/e2e/utils/flows/scenes/removePanel.ts @@ -0,0 +1,17 @@ +import { e2e } from '../..'; + +import { selectPanels } from './selectPanel'; + +export const removePanels = (...panelTitles: Array) => { + selectPanels(panelTitles); + + // Delete the panels + e2e.components.EditPaneHeader.deleteButton().click(); + + // Confirm deletion via modal + e2e.pages.ConfirmModal.delete().click(); +}; + +export const removePanel = (panelTitle: string | RegExp) => { + removePanels(panelTitle); +}; diff --git a/e2e/utils/flows/scenes/selectPanel.ts b/e2e/utils/flows/scenes/selectPanel.ts new file mode 100644 index 00000000000..4ccf5aa9cc3 --- /dev/null +++ b/e2e/utils/flows/scenes/selectPanel.ts @@ -0,0 +1,11 @@ +import { e2e } from '../..'; + +export const selectPanel = (panelTitle: string | RegExp, shift = false) => { + e2e.components.Panels.Panel.headerContainer().contains(panelTitle).click({ shiftKey: shift }); +}; + +export const selectPanels = (panelTitles: Array) => { + for (const panel of panelTitles) { + selectPanel(panel, true); + } +}; diff --git a/e2e/utils/flows/scenes/toggleEditMode.ts b/e2e/utils/flows/scenes/toggleEditMode.ts new file mode 100644 index 00000000000..ec8a75854a2 --- /dev/null +++ b/e2e/utils/flows/scenes/toggleEditMode.ts @@ -0,0 +1,5 @@ +import { e2e } from '../..'; + +export const toggleEditMode = () => { + e2e.components.NavToolbar.editDashboard.editButton().should('be.visible').click(); +}; diff --git a/packages/grafana-e2e-selectors/src/selectors/components.ts b/packages/grafana-e2e-selectors/src/selectors/components.ts index 2d58dd46c03..13c8cd8b56a 100644 --- a/packages/grafana-e2e-selectors/src/selectors/components.ts +++ b/packages/grafana-e2e-selectors/src/selectors/components.ts @@ -33,6 +33,11 @@ export const versionedComponents = { '12.1.0': 'data-testid DashboardEditPaneSplitter primary body', }, }, + EditPaneHeader: { + deleteButton: { + '12.1.0': 'data-testid EditPaneHeader delete panel', + }, + }, TimePicker: { openButton: { [MIN_GRAFANA_VERSION]: 'data-testid TimePicker Open Button', @@ -354,6 +359,9 @@ export const versionedComponents = { content: { '11.1.0': 'data-testid panel content', }, + headerContainer: { + '9.5.0': 'data-testid header-container', + }, headerItems: { '10.2.0': (item: string) => `data-testid Panel header item ${item}`, }, diff --git a/packages/grafana-ui/src/components/PanelChrome/PanelChrome.test.tsx b/packages/grafana-ui/src/components/PanelChrome/PanelChrome.test.tsx index bb3d63d723f..a13c38567b0 100644 --- a/packages/grafana-ui/src/components/PanelChrome/PanelChrome.test.tsx +++ b/packages/grafana-ui/src/components/PanelChrome/PanelChrome.test.tsx @@ -63,7 +63,7 @@ it('renders an empty panel with padding', () => { it('renders panel header if prop title', () => { setup({ title: 'Test Panel Header' }); - expect(screen.getByTestId('header-container')).toBeInTheDocument(); + expect(screen.getByTestId(selectors.components.Panels.Panel.headerContainer)).toBeInTheDocument(); }); // Check for backwards compatibility @@ -79,13 +79,13 @@ it('renders panel with a header if prop leftItems', () => { leftItems: [
This should be a self-contained node
], }); - expect(screen.getByTestId('header-container')).toBeInTheDocument(); + expect(screen.getByTestId(selectors.components.Panels.Panel.headerContainer)).toBeInTheDocument(); }); it('renders panel with a hovering header if prop hoverHeader is true', () => { setup({ title: 'Test Panel Header', hoverHeader: true }); - expect(screen.queryByTestId('header-container')).not.toBeInTheDocument(); + expect(screen.queryByTestId(selectors.components.Panels.Panel.headerContainer)).not.toBeInTheDocument(); }); it('renders panel with a header if prop titleItems', () => { @@ -93,7 +93,7 @@ it('renders panel with a header if prop titleItems', () => { titleItems: [
This should be a self-contained node
], }); - expect(screen.getByTestId('header-container')).toBeInTheDocument(); + expect(screen.getByTestId(selectors.components.Panels.Panel.headerContainer)).toBeInTheDocument(); }); it('renders panel with a header with icons in place if prop titleItems', () => { diff --git a/packages/grafana-ui/src/components/PanelChrome/PanelChrome.tsx b/packages/grafana-ui/src/components/PanelChrome/PanelChrome.tsx index b2644534d11..c042f5d4539 100644 --- a/packages/grafana-ui/src/components/PanelChrome/PanelChrome.tsx +++ b/packages/grafana-ui/src/components/PanelChrome/PanelChrome.tsx @@ -372,7 +372,7 @@ export function PanelChrome({
)}