From 012bfa29be59607129099a2bbb73a7ca11b893b5 Mon Sep 17 00:00:00 2001
From: Sergej-Vlasov <37613182+Sergej-Vlasov@users.noreply.github.com>
Date: Tue, 13 May 2025 13:58:09 +0100
Subject: [PATCH] Dashboards/E2E: Add tests for grouping and ungrouping into
rows and tabs (#105315)
* add e2e for grouping into tabs and rows
* enable kubernetesDashboards feature toggle for e2e tests
* remove unnecessary kubernetesDashboard feature flag enablement
---
.../dashboard-group-panels.spec.ts | 152 ++++++++++++++++++
e2e/utils/flows/scenes/addPanel.ts | 12 +-
e2e/utils/flows/scenes/groupPanels.ts | 15 ++
e2e/utils/flows/scenes/index.ts | 2 +
e2e/utils/flows/scenes/saveDashboard.ts | 8 +
.../src/selectors/components.ts | 6 +
.../layouts-shared/CanvasGridAddActions.tsx | 18 ++-
7 files changed, 209 insertions(+), 4 deletions(-)
create mode 100644 e2e/dashboard-new-layouts/dashboard-group-panels.spec.ts
create mode 100644 e2e/utils/flows/scenes/groupPanels.ts
create mode 100644 e2e/utils/flows/scenes/saveDashboard.ts
diff --git a/e2e/dashboard-new-layouts/dashboard-group-panels.spec.ts b/e2e/dashboard-new-layouts/dashboard-group-panels.spec.ts
new file mode 100644
index 00000000000..f5ea94bc735
--- /dev/null
+++ b/e2e/dashboard-new-layouts/dashboard-group-panels.spec.ts
@@ -0,0 +1,152 @@
+import { e2e } from '../utils';
+
+describe('Grouping panels', () => {
+ beforeEach(() => {
+ e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD'));
+ });
+
+ after(() => {
+ e2e.flows.revertAllChanges();
+ });
+
+ it('can group and ungroup new panels into row', () => {
+ e2e.flows.addDashboard({ title: 'Group new panels into row' });
+ cy.contains('Group new panels into row').should('be.visible');
+
+ // Toggle edit mode
+ e2e.components.NavToolbar.editDashboard.editButton().should('be.visible').click();
+
+ // Add 3 panels
+ e2e.flows.scenes.addFirstPanel();
+ e2e.flows.scenes.addPanel();
+ e2e.flows.scenes.addPanel();
+
+ // Group into row
+ e2e.flows.scenes.groupIntoRow();
+
+ // Verify row and panel titles
+ e2e.components.DashboardRow.title('New row').should('be.visible');
+ e2e.components.Panels.Panel.title('New panel').should('have.length', 3);
+
+ // Save dashboards and reload
+ e2e.flows.scenes.saveDashboard();
+ cy.reload();
+
+ // Verify row and panel titles after reload
+ e2e.components.DashboardRow.title('New row').should('be.visible');
+ e2e.components.Panels.Panel.title('New panel').should('have.length', 3);
+
+ e2e.components.NavToolbar.editDashboard.editButton().should('be.visible').click();
+
+ // Ungroup
+ e2e.flows.scenes.ungroupPanels();
+
+ // Verify Row title is gone
+ e2e.components.DashboardRow.title('New row').should('not.exist');
+ e2e.components.Panels.Panel.title('New panel').should('have.length', 3);
+
+ //Save dashboards and reload
+ e2e.flows.scenes.saveDashboard();
+ cy.reload();
+
+ // Verify Row title is gone
+ e2e.components.DashboardRow.title('New row').should('not.exist');
+ e2e.components.Panels.Panel.title('New panel').should('have.length', 3);
+ });
+
+ it('can group and ungroup new panels into tab', () => {
+ e2e.flows.addDashboard({ title: 'Group new panels into tab' });
+ cy.contains('Group new panels into tab').should('be.visible');
+
+ // Toggle edit mode
+ e2e.components.NavToolbar.editDashboard.editButton().should('be.visible').click();
+
+ // Add 3 panels
+ e2e.flows.scenes.addFirstPanel();
+ e2e.flows.scenes.addPanel();
+ e2e.flows.scenes.addPanel();
+
+ // Group into tab
+ e2e.flows.scenes.groupIntoTab();
+
+ // Verify tab and panel titles
+ e2e.components.Tab.title('New tab').should('be.visible');
+ e2e.components.Panels.Panel.title('New panel').should('have.length', 3);
+
+ // Save dashboards and reload
+ e2e.flows.scenes.saveDashboard();
+ cy.reload();
+
+ // Verify row and panel titles after reload
+ e2e.components.Tab.title('New tab').should('be.visible');
+ e2e.components.Panels.Panel.title('New panel').should('have.length', 3);
+
+ e2e.components.NavToolbar.editDashboard.editButton().should('be.visible').click();
+
+ // Ungroup
+ e2e.flows.scenes.ungroupPanels();
+
+ // Verify Row title is gone
+ e2e.components.Tab.title('New tab').should('not.exist');
+ e2e.components.Panels.Panel.title('New panel').should('have.length', 3);
+
+ // Save dashboards and reload
+ e2e.flows.scenes.saveDashboard();
+ cy.reload();
+
+ // Verify Row title is gone
+ e2e.components.Tab.title('New tab').should('not.exist');
+ e2e.components.Panels.Panel.title('New panel').should('have.length', 3);
+ });
+
+ it('can group and ungroup new panels into tab with row', () => {
+ e2e.flows.addDashboard({ title: 'Group new panels into tab with row' });
+ cy.contains('Group new panels into tab with row').should('be.visible');
+
+ // Toggle edit mode
+ e2e.components.NavToolbar.editDashboard.editButton().should('be.visible').click();
+
+ // Add 3 panels
+ e2e.flows.scenes.addFirstPanel();
+ e2e.flows.scenes.addPanel();
+ e2e.flows.scenes.addPanel();
+
+ // Group into tab
+ e2e.flows.scenes.groupIntoTab();
+ e2e.flows.scenes.groupIntoRow();
+
+ // Verify tab and panel titles
+ e2e.components.Tab.title('New tab').should('be.visible');
+ e2e.components.DashboardRow.title('New row').should('be.visible');
+ e2e.components.Panels.Panel.title('New panel').should('have.length', 3);
+
+ // Save dashboards and reload
+ e2e.flows.scenes.saveDashboard();
+ cy.reload();
+
+ // Verify tab, row and panel titles after reload
+ e2e.components.Tab.title('New tab').should('be.visible');
+ e2e.components.DashboardRow.title('New row').should('be.visible');
+ e2e.components.Panels.Panel.title('New panel').should('have.length', 3);
+
+ e2e.components.NavToolbar.editDashboard.editButton().should('be.visible').click();
+
+ // Ungroup
+ e2e.flows.scenes.ungroupPanels(); // ungroup rows
+ e2e.flows.scenes.ungroupPanels(); // ungroup tabs
+
+ // Verify tab and row titles is gone
+ e2e.components.Tab.title('New tab').should('not.exist');
+ e2e.components.DashboardRow.title('New row').should('not.exist');
+ e2e.components.Panels.Panel.title('New panel').should('have.length', 3);
+
+ // Save dashboards and reload
+ e2e.flows.scenes.saveDashboard();
+ cy.reload();
+
+ // Verify Row title is gone
+ e2e.components.Tab.title('New tab').should('not.exist');
+ e2e.components.DashboardRow.title('New row').should('not.exist');
+ e2e.components.Panels.Panel.title('New panel').should('have.length', 3);
+ });
+});
diff --git a/e2e/utils/flows/scenes/addPanel.ts b/e2e/utils/flows/scenes/addPanel.ts
index bea70e4f4b7..1e7f31d0fe1 100644
--- a/e2e/utils/flows/scenes/addPanel.ts
+++ b/e2e/utils/flows/scenes/addPanel.ts
@@ -1,6 +1,16 @@
import { e2e } from '../..';
export const addPanel = () => {
- e2e.components.DashboardEditPaneSplitter.primaryBody().scrollTo('bottom');
+ e2e.components.DashboardEditPaneSplitter.primaryBody().scrollTo('bottom', { ensureScrollable: false });
e2e.components.CanvasGridAddActions.addPanel().should('be.visible').click();
};
+
+export const addFirstPanel = () => {
+ // add visualization
+ e2e.pages.AddDashboard.itemButton('Create new panel button').should('be.visible').click();
+
+ // close the data source picker modal
+ cy.get('[aria-label="Close"]').click({ force: true });
+
+ e2e.components.NavToolbar.editDashboard.backToDashboardButton().click();
+};
diff --git a/e2e/utils/flows/scenes/groupPanels.ts b/e2e/utils/flows/scenes/groupPanels.ts
new file mode 100644
index 00000000000..750545f89e9
--- /dev/null
+++ b/e2e/utils/flows/scenes/groupPanels.ts
@@ -0,0 +1,15 @@
+import { e2e } from '../..';
+
+export const groupIntoRow = () => {
+ e2e.components.CanvasGridAddActions.groupPanels().click({ scrollBehavior: 'nearest' });
+ cy.contains('Group into row').click();
+};
+
+export const groupIntoTab = () => {
+ e2e.components.CanvasGridAddActions.groupPanels().click({ scrollBehavior: 'nearest' });
+ cy.contains('Group into tab').click();
+};
+
+export const ungroupPanels = () => {
+ e2e.components.CanvasGridAddActions.ungroup().click({ scrollBehavior: 'nearest' });
+};
diff --git a/e2e/utils/flows/scenes/index.ts b/e2e/utils/flows/scenes/index.ts
index fa385607cc8..314f5e4bcaa 100644
--- a/e2e/utils/flows/scenes/index.ts
+++ b/e2e/utils/flows/scenes/index.ts
@@ -2,3 +2,5 @@ export * from './addPanel';
export * from './configurePanel';
export * from './removePanel';
export * from './toggleEditMode';
+export * from './groupPanels';
+export * from './saveDashboard';
diff --git a/e2e/utils/flows/scenes/saveDashboard.ts b/e2e/utils/flows/scenes/saveDashboard.ts
new file mode 100644
index 00000000000..707a01efe94
--- /dev/null
+++ b/e2e/utils/flows/scenes/saveDashboard.ts
@@ -0,0 +1,8 @@
+import { e2e } from '../../index';
+
+export const saveDashboard = () => {
+ e2e.components.NavToolbar.editDashboard.saveButton().click();
+
+ e2e.components.Drawer.DashboardSaveDrawer.saveButton().click();
+ e2e.flows.assertSuccessNotification();
+};
diff --git a/packages/grafana-e2e-selectors/src/selectors/components.ts b/packages/grafana-e2e-selectors/src/selectors/components.ts
index 13c8cd8b56a..084acb8b561 100644
--- a/packages/grafana-e2e-selectors/src/selectors/components.ts
+++ b/packages/grafana-e2e-selectors/src/selectors/components.ts
@@ -27,6 +27,12 @@ export const versionedComponents = {
addPanel: {
'12.1.0': 'data-testid CanvasGridAddActions add-panel',
},
+ groupPanels: {
+ '12.1.0': 'data-testid CanvasGridAddActions group-panels',
+ },
+ ungroup: {
+ '12.1.0': 'data-testid CanvasGridAddActions ungroup',
+ },
},
DashboardEditPaneSplitter: {
primaryBody: {
diff --git a/public/app/features/dashboard-scene/scene/layouts-shared/CanvasGridAddActions.tsx b/public/app/features/dashboard-scene/scene/layouts-shared/CanvasGridAddActions.tsx
index 4baf5ddeb85..54e963a0a30 100644
--- a/public/app/features/dashboard-scene/scene/layouts-shared/CanvasGridAddActions.tsx
+++ b/public/app/features/dashboard-scene/scene/layouts-shared/CanvasGridAddActions.tsx
@@ -59,7 +59,7 @@ export function CanvasGridAddActions({ layoutManager }: Props) {
variant="primary"
fill="text"
icon="layers"
- onClick={() => layoutManager.addPanel(getDefaultVizPanel())}
+ data-testid={selectors.components.CanvasGridAddActions.groupPanels}
>
Group panels
@@ -118,7 +118,13 @@ function UngroupButtonTabs({ parentLayout, onClick }: UngroupButtonProps
+
);
@@ -132,7 +138,13 @@ function UngroupButtonRows({ parentLayout, onClick }: UngroupButtonProps
+
);