diff --git a/e2e/dashboards-edit-v2-suite/dashboards-edit-variables.spec.ts b/e2e/dashboards-edit-v2-suite/dashboards-edit-variables.spec.ts new file mode 100644 index 00000000000..e6f15f8e2e5 --- /dev/null +++ b/e2e/dashboards-edit-v2-suite/dashboards-edit-variables.spec.ts @@ -0,0 +1,60 @@ +import { e2e } from '../utils'; + +const PAGE_UNDER_TEST = 'kVi2Gex7z/test-variable-output'; +const DASHBOARD_NAME = 'Test variable output'; + +describe('Dashboard edit variables', () => { + beforeEach(() => { + e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD')); + }); + + it('can add a new custom variable', () => { + e2e.pages.Dashboards.visit(); + + e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?orgId=1` }); + cy.contains(DASHBOARD_NAME).should('be.visible'); + + const variable: Variable = { + type: 'custom', + name: 'foo', + label: 'Foo', + value: 'one,two,three', + }; + + // common steps to add a new variable + flows.newEditPaneVariableClick(); + flows.newEditPanelCommonVariableInputs(variable); + + // set the custom variable value + e2e.pages.Dashboard.Settings.Variables.Edit.CustomVariable.customValueInput().clear().type(variable.value).blur(); + + // assert the dropdown for the variable is visible and has the correct values + e2e.pages.Dashboard.SubMenu.submenuItemLabels(variable.label).should('be.visible').contains(variable.label); + const values = variable.value.split(','); + e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownValueLinkTexts(values[0]).should('be.visible'); + }); +}); + +// Common flows for adding/editing variables +// TODO: maybe move to e2e flows +const flows = { + newEditPaneVariableClick() { + e2e.components.NavToolbar.editDashboard.editButton().should('be.visible').click(); + e2e.components.PanelEditor.Outline.section().should('be.visible').click(); + e2e.components.PanelEditor.Outline.item('Variables').should('be.visible').click(); + e2e.components.PanelEditor.ElementEditPane.addVariableButton().should('be.visible').click(); + }, + newEditPanelCommonVariableInputs(variable: Variable) { + e2e.components.PanelEditor.ElementEditPane.variableType(variable.type).should('be.visible').click(); + e2e.components.PanelEditor.ElementEditPane.variableNameInput().clear().type(variable.name).blur(); + e2e.components.PanelEditor.ElementEditPane.variableLabelInput().clear().type(variable.label).blur(); + }, +}; + +type Variable = { + type: string; + name: string; + label: string; + description?: string; + value: string; +}; diff --git a/e2e/run-suite b/e2e/run-suite index 28ed2f6bd8d..c5d1f896a35 100755 --- a/e2e/run-suite +++ b/e2e/run-suite @@ -30,6 +30,7 @@ rootForEnterpriseSuite="./e2e/extensions-suite" rootForOldArch="./e2e/old-arch" rootForKubernetesDashboards="./e2e/dashboards-suite" rootForSearchDashboards="./e2e/dashboards-search-suite" +rootForEditDashboards="./e2e/dashboards-edit-v2-suite" declare -A cypressConfig=( [screenshotsFolder]=./e2e/"${args[0]}"/screenshots @@ -149,6 +150,25 @@ case "$1" in ;; esac ;; + "dashboards-edit-v2") + env[kubernetesDashboards]=true + env[dashboardNewLayouts]=true + cypressConfig[specPattern]=$rootForEditDashboards/$testFilesForSingleSuite + cypressConfig[video]=false + case "$2" in + "debug") + echo -e "Debug mode" + env[SLOWMO]=1 + PARAMS="--no-exit" + enterpriseSuite=$(basename "${args[2]}") + ;; + "dev") + echo "Dev mode" + CMD="cypress open" + enterpriseSuite=$(basename "${args[2]}") + ;; + esac + ;; "enterprise-smtp") env[SMTP_PLUGIN_ENABLED]=true cypressConfig[specPattern]=./e2e/extensions/enterprise/smtp-suite/$testFilesForSingleSuite diff --git a/package.json b/package.json index 1fb6e4e45f5..6251c0d989f 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,8 @@ "e2e:old-arch": "./e2e/start-and-run-suite old-arch", "e2e:schema-v2": "./e2e/start-and-run-suite dashboards-schema-v2", "e2e:dashboards-search": "./e2e/start-and-run-suite dashboards-search", + "e2e:dashboards-edit-v2": "./e2e/start-and-run-suite dashboards-edit-v2", + "e2e:dashboards-edit-v2:dev": "./e2e/start-and-run-suite dashboards-edit-v2 dev", "e2e:debug": "./e2e/start-and-run-suite debug", "e2e:dev": "./e2e/start-and-run-suite dev", "e2e:benchmark:live": "./e2e/start-and-run-suite benchmark live", diff --git a/packages/grafana-e2e-selectors/src/selectors/components.ts b/packages/grafana-e2e-selectors/src/selectors/components.ts index 1d708a77a14..df16879214a 100644 --- a/packages/grafana-e2e-selectors/src/selectors/components.ts +++ b/packages/grafana-e2e-selectors/src/selectors/components.ts @@ -532,6 +532,33 @@ export const versionedComponents = { measureButton: { '9.2.0': 'show measure tools', }, + + Outline: { + section: { + '12.0.0': 'data-testid Outline section', + }, + node: { + '12.0.0': (type: string) => `data-testid outline node ${type}`, + }, + item: { + '12.0.0': (type: string) => `data-testid outline item ${type}`, + }, + }, + + ElementEditPane: { + variableType: { + '12.0.0': (type?: string) => `data-testid variable type ${type}`, + }, + addVariableButton: { + '12.0.0': 'data-testid add variable button', + }, + variableNameInput: { + '12.0.0': 'data-testid variable name input', + }, + variableLabelInput: { + '12.0.0': 'data-testid variable label input', + }, + }, }, PanelInspector: { Data: { diff --git a/public/app/features/dashboard-scene/edit-pane/DashboardEditPane.tsx b/public/app/features/dashboard-scene/edit-pane/DashboardEditPane.tsx index a667b877357..490ac81bd09 100644 --- a/public/app/features/dashboard-scene/edit-pane/DashboardEditPane.tsx +++ b/public/app/features/dashboard-scene/edit-pane/DashboardEditPane.tsx @@ -3,6 +3,7 @@ import { Resizable } from 're-resizable'; import { useLocalStorage } from 'react-use'; import { GrafanaTheme2 } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; import { SceneObjectState, SceneObjectBase, SceneObject, sceneGraph, useSceneObjectState } from '@grafana/scenes'; import { ElementSelectionContextItem, @@ -272,11 +273,12 @@ export function DashboardEditPaneRenderer({ editPane, isCollapsed, onToggleColla role="button" onClick={() => setOutlineCollapsed(!outlineCollapsed)} className={styles.outlineCollapseButton} + data-testid={selectors.components.PanelEditor.Outline.section} > Outline - + {!outlineCollapsed && (
diff --git a/public/app/features/dashboard-scene/edit-pane/DashboardOutline.tsx b/public/app/features/dashboard-scene/edit-pane/DashboardOutline.tsx index 58076081f00..725714df3d8 100644 --- a/public/app/features/dashboard-scene/edit-pane/DashboardOutline.tsx +++ b/public/app/features/dashboard-scene/edit-pane/DashboardOutline.tsx @@ -3,6 +3,7 @@ import { sortBy } from 'lodash'; import React, { useEffect, useMemo, useState } from 'react'; import { GrafanaTheme2 } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; import { SceneObject } from '@grafana/scenes'; import { Box, Icon, Text, useElementSelection, useStyles2, useTheme2 } from '@grafana/ui'; import { t, Trans } from 'app/core/internationalization'; @@ -88,7 +89,12 @@ function DashboardOutlineNode({ onPointerDown={onNodeClicked} > {elementInfo.isContainer && ( - )} @@ -96,6 +102,7 @@ function DashboardOutlineNode({ role="button" className={cx(styles.nodeName, isCloned && styles.nodeNameClone)} onDoubleClick={outlineRename.onNameDoubleClicked} + data-testid={selectors.components.PanelEditor.Outline.item(instanceName)} > {outlineRename.isRenaming ? ( diff --git a/public/app/features/dashboard-scene/scene/new-toolbar/actions/ToolbarSwitch.tsx b/public/app/features/dashboard-scene/scene/new-toolbar/actions/ToolbarSwitch.tsx index bd693d10e09..c057a50be2b 100644 --- a/public/app/features/dashboard-scene/scene/new-toolbar/actions/ToolbarSwitch.tsx +++ b/public/app/features/dashboard-scene/scene/new-toolbar/actions/ToolbarSwitch.tsx @@ -11,7 +11,7 @@ interface Props { checkedIcon?: IconName; checkedLabel?: string; disabled?: boolean; - 'data-testId'?: string; + 'data-testid'?: string; onClick: (evt: MouseEvent) => void; } @@ -23,7 +23,7 @@ export const ToolbarSwitch = ({ checkedLabel, disabled, onClick, - 'data-testId': dataTestId, + 'data-testid': dataTestId, }: Props) => { const styles = useStyles2(getStyles); diff --git a/public/app/features/dashboard-scene/settings/variables/VariableEditableElement.tsx b/public/app/features/dashboard-scene/settings/variables/VariableEditableElement.tsx index 213557fc8c4..2a639a2e5c8 100644 --- a/public/app/features/dashboard-scene/settings/variables/VariableEditableElement.tsx +++ b/public/app/features/dashboard-scene/settings/variables/VariableEditableElement.tsx @@ -1,6 +1,7 @@ import { FormEvent, useMemo, useState } from 'react'; import { VariableHide } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; import { locationService } from '@grafana/runtime'; import { LocalValueVariable, MultiValueVariable, SceneVariable, SceneVariableSet } from '@grafana/scenes'; import { Input, TextArea, Button, Field, Box, Stack } from '@grafana/ui'; @@ -143,14 +144,27 @@ function VariableNameInput({ variable, isNewElement }: { variable: SceneVariable return ( - + ); } function VariableLabelInput({ variable }: VariableInputProps) { const { label } = variable.useState(); - return variable.setState({ label: e.currentTarget.value })} />; + return ( + variable.setState({ label: e.currentTarget.value })} + data-testid={selectors.components.PanelEditor.ElementEditPane.variableLabelInput} + /> + ); } function VariableDescriptionTextArea({ variable }: VariableInputProps) { diff --git a/public/app/features/dashboard-scene/settings/variables/VariableSetEditableElement.tsx b/public/app/features/dashboard-scene/settings/variables/VariableSetEditableElement.tsx index 442f7c58b47..b52127ad95b 100644 --- a/public/app/features/dashboard-scene/settings/variables/VariableSetEditableElement.tsx +++ b/public/app/features/dashboard-scene/settings/variables/VariableSetEditableElement.tsx @@ -3,6 +3,7 @@ import { useMemo } from 'react'; import { useToggle } from 'react-use'; import { GrafanaTheme2 } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; import { SceneVariable, SceneVariableSet } from '@grafana/scenes'; import { Stack, Button, useStyles2, Text, Box, Card } from '@grafana/ui'; import { t, Trans } from 'app/core/internationalization'; @@ -87,7 +88,14 @@ function VariableList({ set }: { set: SceneVariableSet }) { ))} {canAdd && ( - @@ -115,6 +123,7 @@ function VariableTypeSelection({ onAddVariable }: VariableTypeSelectionProps) { onClick={() => onAddVariable(option.value!)} key={option.value} title={t('dashboard.edit-pane.variables.select-type-card-tooltip', 'Click to select type')} + data-testid={selectors.components.PanelEditor.ElementEditPane.variableType(option.value!)} > {option.label} {option.description}