diff --git a/devenv/dev-dashboards/feature-templating/testdata-test-variable-output.json b/devenv/dev-dashboards/feature-templating/testdata-test-variable-output.json new file mode 100644 index 00000000000..ed8abf12fd0 --- /dev/null +++ b/devenv/dev-dashboards/feature-templating/testdata-test-variable-output.json @@ -0,0 +1,76 @@ +{ + "__inputs": [], + "__elements": [], + "__requires": [ + { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "8.4.0-pre" + }, + { + "type": "panel", + "id": "text", + "name": "Text", + "version": "" + } + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "target": { + "limit": 100, + "matchAny": false, + "tags": [], + "type": "dashboard" + }, + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "links": [], + "liveNow": false, + "panels": [ + { + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 2, + "options": { + "mode": "markdown", + "content": "VariableUnderTest: $VariableUnderTest" + }, + "pluginVersion": "8.4.0-pre", + "title": "Panel Title", + "type": "text" + } + ], + "schemaVersion": 35, + "style": "dark", + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Test variable output", + "uid": "kVi2Gex7z", + "version": 2, + "weekStart": "" +} diff --git a/e2e/dashboards-suite/new-constant-variable.spec.ts b/e2e/dashboards-suite/new-constant-variable.spec.ts new file mode 100644 index 00000000000..a173a5cf6fb --- /dev/null +++ b/e2e/dashboards-suite/new-constant-variable.spec.ts @@ -0,0 +1,31 @@ +import { e2e } from '@grafana/e2e'; + +const PAGE_UNDER_TEST = 'kVi2Gex7z/test-variable-output'; + +describe('Variables - Constant', () => { + it('can add a new text box variable', () => { + e2e.flows.login('admin', 'admin'); + e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?orgId=1&editview=templating` }); + + // Create a new "Constant" variable + e2e.components.CallToActionCard.buttonV2('Add variable').click(); + + e2e.pages.Dashboard.Settings.Variables.Edit.General.generalTypeSelect().type('Constant{enter}'); + e2e.pages.Dashboard.Settings.Variables.Edit.General.generalNameInput().clear().type('VariableUnderTest').blur(); + e2e.pages.Dashboard.Settings.Variables.Edit.General.generalLabelInput().type('Variable under test').blur(); + e2e.pages.Dashboard.Settings.Variables.Edit.ConstantVariable.constantOptionsQueryInput().type('pesto').blur(); + + e2e.pages.Dashboard.Settings.Variables.Edit.General.previewOfValuesOption().eq(0).should('have.text', 'pesto'); + + // Navigate back to the homepage and change the selected variable value + e2e.pages.Dashboard.Settings.Variables.Edit.General.submitButton().click(); + e2e.components.BackButton.backArrow().should('be.visible').click({ force: true }); + e2e.components.RefreshPicker.runButtonV2().click(); + + // Assert it was rendered + e2e().get('.markdown-html').should('include.text', 'VariableUnderTest: pesto'); + + // Assert the variable is not visible in the dashboard nav + e2e.pages.Dashboard.SubMenu.submenuItemLabels('Variable under test').should('not.exist'); + }); +}); diff --git a/e2e/dashboards-suite/new-custom-variable.spec.ts b/e2e/dashboards-suite/new-custom-variable.spec.ts new file mode 100644 index 00000000000..28aaca032b9 --- /dev/null +++ b/e2e/dashboards-suite/new-custom-variable.spec.ts @@ -0,0 +1,60 @@ +import { e2e } from '@grafana/e2e'; + +const PAGE_UNDER_TEST = 'kVi2Gex7z/test-variable-output'; + +function fillInCustomVariable(name: string, label: string, value: string) { + e2e.pages.Dashboard.Settings.Variables.Edit.General.generalTypeSelect().type('Custom{enter}'); + e2e.pages.Dashboard.Settings.Variables.Edit.General.generalNameInput().clear().type(name).blur(); + e2e.pages.Dashboard.Settings.Variables.Edit.General.generalLabelInput().type(label).blur(); + e2e.pages.Dashboard.Settings.Variables.Edit.CustomVariable.customValueInput().type(value).blur(); +} + +function assertPreviewValues(expectedValues: string[]) { + for (const expected of expectedValues) { + const index = expectedValues.indexOf(expected); + e2e.pages.Dashboard.Settings.Variables.Edit.General.previewOfValuesOption().eq(index).should('have.text', expected); + } +} + +describe('Variables - Custom', () => { + it('can add a custom template variable', () => { + e2e.flows.login('admin', 'admin'); + e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?orgId=1&editview=templating` }); + + // Create a new "Custom" variable + e2e.components.CallToActionCard.buttonV2('Add variable').click(); + fillInCustomVariable('VariableUnderTest', 'Variable under test', 'one,two,three'); + assertPreviewValues(['one', 'two', 'three']); + + // Navigate back to the homepage and change the selected variable value + e2e.pages.Dashboard.Settings.Variables.Edit.General.submitButton().click(); + e2e.components.BackButton.backArrow().should('be.visible').click({ force: true }); + e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownValueLinkTexts('one').click(); + e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('two').click(); + + // Assert it was rendered + e2e().get('.markdown-html').should('include.text', 'VariableUnderTest: two'); + }); + + it('can add a custom template variable with labels', () => { + e2e.flows.login('admin', 'admin'); + e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?orgId=1&editview=templating` }); + + // Create a new "Custom" variable + e2e.components.CallToActionCard.buttonV2('Add variable').click(); + e2e.pages.Dashboard.Settings.Variables.Edit.General.generalTypeSelect().type('Custom{enter}'); + + // Set it's name, label, and content + fillInCustomVariable('VariableUnderTest', 'Variable under test', 'One : 1,Two : 2, Three : 3'); + assertPreviewValues(['One', 'Two', 'Three']); + + // Navigate back to the homepage and change the selected variable value + e2e.pages.Dashboard.Settings.Variables.Edit.General.submitButton().click(); + e2e.components.BackButton.backArrow().should('be.visible').click({ force: true }); + e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownValueLinkTexts('One').click(); + e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('Two').click(); + + // Assert it was rendered + e2e().get('.markdown-html').should('include.text', 'VariableUnderTest: 2'); + }); +}); diff --git a/e2e/dashboards-suite/new-query-variable.spec.ts b/e2e/dashboards-suite/new-query-variable.spec.ts index 4efd16bd1bf..206e014a15b 100644 --- a/e2e/dashboards-suite/new-query-variable.spec.ts +++ b/e2e/dashboards-suite/new-query-variable.spec.ts @@ -2,7 +2,7 @@ import { e2e } from '@grafana/e2e'; const PAGE_UNDER_TEST = '-Y-tnEDWk/templating-nested-template-variables'; -describe('Variables - Add variable', () => { +describe('Variables - Query - Add variable', () => { it('query variable should be default and default fields should be correct', () => { e2e.flows.login('admin', 'admin'); e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?orgId=1&editview=templating` }); diff --git a/e2e/dashboards-suite/new-text-box-variable.spec.ts b/e2e/dashboards-suite/new-text-box-variable.spec.ts new file mode 100644 index 00000000000..bb19b03e4bc --- /dev/null +++ b/e2e/dashboards-suite/new-text-box-variable.spec.ts @@ -0,0 +1,28 @@ +import { e2e } from '@grafana/e2e'; + +const PAGE_UNDER_TEST = 'kVi2Gex7z/test-variable-output'; + +describe('Variables - Text box', () => { + it('can add a new text box variable', () => { + e2e.flows.login('admin', 'admin'); + e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?orgId=1&editview=templating` }); + + // Create a new "Custom" variable + e2e.components.CallToActionCard.buttonV2('Add variable').click(); + + e2e.pages.Dashboard.Settings.Variables.Edit.General.generalTypeSelect().type('Text box{enter}'); + e2e.pages.Dashboard.Settings.Variables.Edit.General.generalNameInput().clear().type('VariableUnderTest').blur(); + e2e.pages.Dashboard.Settings.Variables.Edit.General.generalLabelInput().type('Variable under test').blur(); + e2e.pages.Dashboard.Settings.Variables.Edit.TextBoxVariable.textBoxOptionsQueryInput().type('cat-dog').blur(); + + e2e.pages.Dashboard.Settings.Variables.Edit.General.previewOfValuesOption().eq(0).should('have.text', 'cat-dog'); + + // Navigate back to the homepage and change the selected variable value + e2e.pages.Dashboard.Settings.Variables.Edit.General.submitButton().click(); + e2e.components.BackButton.backArrow().should('be.visible').click({ force: true }); + e2e().get('#VariableUnderTest').clear().type('dog-cat').blur(); + + // Assert it was rendered + e2e().get('.markdown-html').should('include.text', 'VariableUnderTest: dog-cat'); + }); +}); diff --git a/packages/grafana-e2e-selectors/src/selectors/pages.ts b/packages/grafana-e2e-selectors/src/selectors/pages.ts index 842d47e33c7..ae1ca74046a 100644 --- a/packages/grafana-e2e-selectors/src/selectors/pages.ts +++ b/packages/grafana-e2e-selectors/src/selectors/pages.ts @@ -135,6 +135,9 @@ export const Pages = { TextBoxVariable: { textBoxOptionsQueryInput: 'Variable editor Form TextBox Query field', }, + CustomVariable: { + customValueInput: 'data-testid custom-variable-input', + }, }, }, }, diff --git a/public/app/features/variables/custom/CustomVariableEditor.tsx b/public/app/features/variables/custom/CustomVariableEditor.tsx index 9f73ec8f945..64a76e1b3b6 100644 --- a/public/app/features/variables/custom/CustomVariableEditor.tsx +++ b/public/app/features/variables/custom/CustomVariableEditor.tsx @@ -5,6 +5,7 @@ import { OnPropChangeArguments, VariableEditorProps } from '../editor/types'; import { connectWithStore } from 'app/core/utils/connectWithReduxStore'; import { MapDispatchToProps, MapStateToProps } from 'react-redux'; import { VerticalGroup } from '@grafana/ui'; +import { selectors } from '@grafana/e2e-selectors'; import { StoreState } from 'app/types'; import { changeVariableMultiValue } from '../state/actions'; import { VariableSectionHeader } from '../editor/VariableSectionHeader'; @@ -55,6 +56,7 @@ class CustomVariableEditorUnconnected extends PureComponent { required width={50} labelWidth={27} + testId={selectors.pages.Dashboard.Settings.Variables.Edit.CustomVariable.customValueInput} /> { ariaLabel?: string; required?: boolean; labelWidth?: number; + testId?: string; onBlur?: (event: FormEvent) => void; } @@ -27,6 +28,7 @@ export function VariableTextAreaField({ required, width, labelWidth, + testId, }: PropsWithChildren>): ReactElement { const styles = useStyles(getStyles); const getLineCount = useCallback((value: any) => { @@ -49,6 +51,7 @@ export function VariableTextAreaField({ aria-label={ariaLabel} cols={width} className={styles.textarea} + data-testid={testId} /> );