Commit 6c5a0421 by Steven Vachon Committed by GitHub

@grafana/e2e: improve types (#27348)

parent a8db544e
...@@ -15,24 +15,32 @@ export interface AddDashboardConfig { ...@@ -15,24 +15,32 @@ export interface AddDashboardConfig {
annotations: AddAnnotationConfig[]; annotations: AddAnnotationConfig[];
timeRange: TimeRangeConfig; timeRange: TimeRangeConfig;
title: string; title: string;
variables: Array<Partial<AddVariableConfig>>; variables: PartialAddVariableConfig[];
} }
export interface AddVariableConfig { interface AddVariableDefault {
hide: string;
type: string;
}
interface AddVariableOptional {
constantValue?: string; constantValue?: string;
dataSource?: string; dataSource?: string;
hide: string;
label?: string; label?: string;
name: string;
query?: string; query?: string;
regex?: string; regex?: string;
type: string;
} }
// @todo improve config input/output: https://stackoverflow.com/a/63507459/923745 interface AddVariableRequired {
// @todo this actually returns type `Cypress.Chainable` name: string;
export const addDashboard = (config?: Partial<AddDashboardConfig>): any => { }
const fullConfig = {
export type PartialAddVariableConfig = Partial<AddVariableDefault> & AddVariableOptional & AddVariableRequired;
export type AddVariableConfig = AddVariableDefault & AddVariableOptional & AddVariableRequired;
// @todo this actually returns type `Cypress.Chainable<AddDashboardConfig>`
export const addDashboard = (config?: Partial<AddDashboardConfig>) => {
const fullConfig: AddDashboardConfig = {
annotations: [], annotations: [],
title: `e2e-${uuidv4()}`, title: `e2e-${uuidv4()}`,
variables: [], variables: [],
...@@ -43,7 +51,7 @@ export const addDashboard = (config?: Partial<AddDashboardConfig>): any => { ...@@ -43,7 +51,7 @@ export const addDashboard = (config?: Partial<AddDashboardConfig>): any => {
zone: 'Coordinated Universal Time', zone: 'Coordinated Universal Time',
...config?.timeRange, ...config?.timeRange,
}, },
} as AddDashboardConfig; };
const { annotations, timeRange, title, variables } = fullConfig; const { annotations, timeRange, title, variables } = fullConfig;
...@@ -54,7 +62,9 @@ export const addDashboard = (config?: Partial<AddDashboardConfig>): any => { ...@@ -54,7 +62,9 @@ export const addDashboard = (config?: Partial<AddDashboardConfig>): any => {
if (annotations.length > 0 || variables.length > 0) { if (annotations.length > 0 || variables.length > 0) {
e2e.pages.Dashboard.Toolbar.toolbarItems('Dashboard settings').click(); e2e.pages.Dashboard.Toolbar.toolbarItems('Dashboard settings').click();
addAnnotations(annotations); addAnnotations(annotations);
addVariables(variables);
fullConfig.variables = addVariables(variables);
e2e.components.BackButton.backArrow().click(); e2e.components.BackButton.backArrow().click();
} }
...@@ -137,13 +147,12 @@ const addAnnotation = (config: AddAnnotationConfig, isFirst: boolean) => { ...@@ -137,13 +147,12 @@ const addAnnotation = (config: AddAnnotationConfig, isFirst: boolean) => {
.click(); .click();
}; };
// @todo this actually returns type `Cypress.Chainable` const addAnnotations = (configs: AddAnnotationConfig[]) => {
const addAnnotations = (configs: AddAnnotationConfig[]): any => {
if (configs.length > 0) { if (configs.length > 0) {
e2e.pages.Dashboard.Settings.General.sectionItems('Annotations').click(); e2e.pages.Dashboard.Settings.General.sectionItems('Annotations').click();
} }
return configs.map((config, i) => addAnnotation(config, i === 0)); return configs.forEach((config, i) => addAnnotation(config, i === 0));
}; };
export const VARIABLE_HIDE_LABEL = 'Label'; export const VARIABLE_HIDE_LABEL = 'Label';
...@@ -155,13 +164,12 @@ export const VARIABLE_TYPE_CONSTANT = 'Constant'; ...@@ -155,13 +164,12 @@ export const VARIABLE_TYPE_CONSTANT = 'Constant';
export const VARIABLE_TYPE_DATASOURCE = 'Datasource'; export const VARIABLE_TYPE_DATASOURCE = 'Datasource';
export const VARIABLE_TYPE_QUERY = 'Query'; export const VARIABLE_TYPE_QUERY = 'Query';
// @todo this actually returns type `Cypress.Chainable` const addVariable = (config: PartialAddVariableConfig, isFirst: boolean): AddVariableConfig => {
const addVariable = (config: Partial<AddVariableConfig>, isFirst: boolean): any => {
const fullConfig = { const fullConfig = {
hide: VARIABLE_HIDE_NOTHING, hide: VARIABLE_HIDE_NOTHING,
type: VARIABLE_TYPE_QUERY, type: VARIABLE_TYPE_QUERY,
...config, ...config,
} as AddVariableConfig; };
if (isFirst) { if (isFirst) {
e2e.pages.Dashboard.Settings.Variables.List.addVariableCTA().click(); e2e.pages.Dashboard.Settings.Variables.List.addVariableCTA().click();
...@@ -227,8 +235,7 @@ const addVariable = (config: Partial<AddVariableConfig>, isFirst: boolean): any ...@@ -227,8 +235,7 @@ const addVariable = (config: Partial<AddVariableConfig>, isFirst: boolean): any
return fullConfig; return fullConfig;
}; };
// @todo this actually returns type `Cypress.Chainable` const addVariables = (configs: PartialAddVariableConfig[]): AddVariableConfig[] => {
const addVariables = (configs: Array<Partial<AddVariableConfig>>): any => {
if (configs.length > 0) { if (configs.length > 0) {
e2e.pages.Dashboard.Settings.General.sectionItems('Variables').click(); e2e.pages.Dashboard.Settings.General.sectionItems('Variables').click();
} }
......
...@@ -9,16 +9,15 @@ export interface AddDataSourceConfig { ...@@ -9,16 +9,15 @@ export interface AddDataSourceConfig {
basicAuthUser: string; basicAuthUser: string;
checkHealth: boolean; checkHealth: boolean;
expectedAlertMessage: string | RegExp; expectedAlertMessage: string | RegExp;
form: Function; form: () => void;
name: string; name: string;
skipTlsVerify: boolean; skipTlsVerify: boolean;
type: string; type: string;
} }
// @todo improve config input/output: https://stackoverflow.com/a/63507459/923745 // @todo this actually returns type `Cypress.Chainable<AddDaaSourceConfig>`
// @todo this actually returns type `Cypress.Chainable` export const addDataSource = (config?: Partial<AddDataSourceConfig>) => {
export const addDataSource = (config?: Partial<AddDataSourceConfig>): any => { const fullConfig: AddDataSourceConfig = {
const fullConfig = {
basicAuth: false, basicAuth: false,
basicAuthPassword: '', basicAuthPassword: '',
basicAuthUser: '', basicAuthUser: '',
...@@ -29,7 +28,7 @@ export const addDataSource = (config?: Partial<AddDataSourceConfig>): any => { ...@@ -29,7 +28,7 @@ export const addDataSource = (config?: Partial<AddDataSourceConfig>): any => {
skipTlsVerify: false, skipTlsVerify: false,
type: 'TestData DB', type: 'TestData DB',
...config, ...config,
} as AddDataSourceConfig; };
const { const {
basicAuth, basicAuth,
......
import { configurePanel, ConfigurePanelConfig } from './configurePanel'; import { configurePanel, PartialAddPanelConfig } from './configurePanel';
import { getScenarioContext } from '../support/scenarioContext'; import { getScenarioContext } from '../support/scenarioContext';
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
// @todo `Omit` 'isExplore' export const addPanel = (config?: Partial<PartialAddPanelConfig>) =>
export interface AddPanelConfig extends ConfigurePanelConfig {
dataSourceName: string;
queriesForm: (config: AddPanelConfig) => void;
visualizationName: string;
}
// @todo improve config input/output: https://stackoverflow.com/a/63507459/923745
// @todo this actually returns type `Cypress.Chainable`
export const addPanel = (config?: Partial<AddPanelConfig>): any =>
getScenarioContext().then(({ lastAddedDataSource }: any) => getScenarioContext().then(({ lastAddedDataSource }: any) =>
configurePanel( configurePanel({
{
dataSourceName: lastAddedDataSource, dataSourceName: lastAddedDataSource,
panelTitle: `e2e-${uuidv4()}`, panelTitle: `e2e-${uuidv4()}`,
...config, ...config,
} as AddPanelConfig, isEdit: false,
false isExplore: false,
) })
); );
...@@ -5,45 +5,75 @@ import { selectOption } from './selectOption'; ...@@ -5,45 +5,75 @@ import { selectOption } from './selectOption';
import { setDashboardTimeRange } from './setDashboardTimeRange'; import { setDashboardTimeRange } from './setDashboardTimeRange';
import { setTimeRange, TimeRangeConfig } from './setTimeRange'; import { setTimeRange, TimeRangeConfig } from './setTimeRange';
export interface ConfigurePanelConfig { interface AddPanelOverrides {
dataSourceName: string;
queriesForm: (config: AddPanelConfig) => void;
panelTitle: string;
}
interface EditPanelOverrides {
queriesForm?: (config: EditPanelConfig) => void;
panelTitle: string;
}
interface ConfigurePanelDefault {
chartData: { chartData: {
method: string; method: string;
route: string | RegExp; route: string | RegExp;
}; };
dashboardUid: string; dashboardUid: string;
dataSourceName?: string;
isExplore: boolean;
matchScreenshot: boolean; matchScreenshot: boolean;
queriesForm?: (config: any) => void; saveDashboard: boolean;
panelTitle: string;
screenshotName: string; screenshotName: string;
timeRange?: TimeRangeConfig;
visitDashboardAtStart: boolean; // @todo remove when possible visitDashboardAtStart: boolean; // @todo remove when possible
}
interface ConfigurePanelOptional {
dataSourceName?: string;
queriesForm?: (config: ConfigurePanelConfig) => void;
panelTitle?: string;
timeRange?: TimeRangeConfig;
visualizationName?: string; visualizationName?: string;
} }
// @todo improve config input/output: https://stackoverflow.com/a/63507459/923745 interface ConfigurePanelRequired {
// @todo this actually returns type `Cypress.Chainable` isEdit: boolean;
export const configurePanel = (config: Partial<ConfigurePanelConfig>, isEdit: boolean): any => isExplore: boolean;
}
export type PartialConfigurePanelConfig = Partial<ConfigurePanelDefault> &
ConfigurePanelOptional &
ConfigurePanelRequired;
export type ConfigurePanelConfig = ConfigurePanelDefault & ConfigurePanelOptional & ConfigurePanelRequired;
export type PartialAddPanelConfig = PartialConfigurePanelConfig & AddPanelOverrides;
export type AddPanelConfig = ConfigurePanelConfig & AddPanelOverrides;
export type PartialEditPanelConfig = PartialConfigurePanelConfig & EditPanelOverrides;
export type EditPanelConfig = ConfigurePanelConfig & EditPanelOverrides;
// @todo this actually returns type `Cypress.Chainable<AddPanelConfig | EditPanelConfig | ConfigurePanelConfig>`
export const configurePanel = (config: PartialAddPanelConfig | PartialEditPanelConfig | PartialConfigurePanelConfig) =>
getScenarioContext().then(({ lastAddedDashboardUid }: any) => { getScenarioContext().then(({ lastAddedDashboardUid }: any) => {
const fullConfig = { const fullConfig: AddPanelConfig | EditPanelConfig | ConfigurePanelConfig = {
chartData: { chartData: {
method: 'POST', method: 'POST',
route: '/api/ds/query', route: '/api/ds/query',
}, },
dashboardUid: lastAddedDashboardUid, dashboardUid: lastAddedDashboardUid,
isExplore: false,
matchScreenshot: false, matchScreenshot: false,
saveDashboard: true, saveDashboard: true,
screenshotName: 'panel-visualization', screenshotName: 'panel-visualization',
visitDashboardAtStart: true, visitDashboardAtStart: true,
...config, ...config,
} as ConfigurePanelConfig; };
const { const {
chartData, chartData,
dashboardUid, dashboardUid,
dataSourceName, dataSourceName,
isEdit,
isExplore, isExplore,
matchScreenshot, matchScreenshot,
panelTitle, panelTitle,
...@@ -54,6 +84,10 @@ export const configurePanel = (config: Partial<ConfigurePanelConfig>, isEdit: bo ...@@ -54,6 +84,10 @@ export const configurePanel = (config: Partial<ConfigurePanelConfig>, isEdit: bo
visualizationName, visualizationName,
} = fullConfig; } = fullConfig;
if (isEdit && isExplore) {
throw new TypeError('Invalid configuration');
}
if (isExplore) { if (isExplore) {
e2e.pages.Explore.visit(); e2e.pages.Explore.visit();
} else { } else {
...@@ -108,7 +142,7 @@ export const configurePanel = (config: Partial<ConfigurePanelConfig>, isEdit: bo ...@@ -108,7 +142,7 @@ export const configurePanel = (config: Partial<ConfigurePanelConfig>, isEdit: bo
.find('[value="Panel Title"]') .find('[value="Panel Title"]')
.scrollIntoView() .scrollIntoView()
.clear() .clear()
.type(panelTitle); .type(panelTitle as string);
} }
if (visualizationName) { if (visualizationName) {
......
import { configurePanel, ConfigurePanelConfig } from './configurePanel'; import { configurePanel, PartialEditPanelConfig } from './configurePanel';
// @todo `Omit` 'isExplore' export const editPanel = (config: Partial<PartialEditPanelConfig>) =>
export interface EditPanelConfig extends ConfigurePanelConfig { configurePanel({
queriesForm?: (config: EditPanelConfig) => void; ...config,
} isEdit: true,
isExplore: false,
// @todo improve config input/output: https://stackoverflow.com/a/63507459/923745 });
// @todo this actually returns type `Cypress.Chainable`
export const editPanel = (config: Partial<EditPanelConfig>): any => configurePanel(config, true);
import { configurePanel, ConfigurePanelConfig } from './configurePanel'; import { configurePanel, PartialConfigurePanelConfig } from './configurePanel';
import { getScenarioContext } from '../support/scenarioContext'; import { getScenarioContext } from '../support/scenarioContext';
// @todo `Omit` 'dashboardUid' and 'panelTitle' export const explore = (config: Partial<PartialConfigurePanelConfig>) =>
export interface ExploreConfig extends ConfigurePanelConfig {
queriesForm: (config: ExploreConfig) => void;
}
// @todo improve config input/output: https://stackoverflow.com/a/63507459/923745
// @todo this actually returns type `Cypress.Chainable`
export const explore = (config: Partial<ExploreConfig>): any =>
getScenarioContext().then(({ lastAddedDataSource }: any) => getScenarioContext().then(({ lastAddedDataSource }: any) =>
configurePanel( configurePanel({
{
dataSourceName: lastAddedDataSource, dataSourceName: lastAddedDataSource,
isExplore: true,
screenshotName: 'explore-graph', screenshotName: 'explore-graph',
...config, ...config,
isEdit: false,
isExplore: true,
timeRange: { timeRange: {
from: '2020-01-01 00:00:00', from: '2020-01-01 00:00:00',
to: '2020-01-01 06:00:00', to: '2020-01-01 06:00:00',
zone: 'Coordinated Universal Time', zone: 'Coordinated Universal Time',
...config.timeRange, ...config.timeRange,
}, },
} as ExploreConfig, })
false
)
); );
...@@ -2,18 +2,24 @@ import { e2e } from '../index'; ...@@ -2,18 +2,24 @@ import { e2e } from '../index';
import { getScenarioContext } from '../support/scenarioContext'; import { getScenarioContext } from '../support/scenarioContext';
import { setDashboardTimeRange, TimeRangeConfig } from './setDashboardTimeRange'; import { setDashboardTimeRange, TimeRangeConfig } from './setDashboardTimeRange';
export interface OpenDashboardConfig { interface OpenDashboardDefault {
timeRange?: TimeRangeConfig;
uid: string; uid: string;
} }
// @todo improve config input/output: https://stackoverflow.com/a/63507459/923745 interface OpenDashboardOptional {
export const openDashboard = (config?: Partial<OpenDashboardConfig>) => timeRange?: TimeRangeConfig;
}
export type PartialOpenDashboardConfig = Partial<OpenDashboardDefault> & OpenDashboardOptional;
export type OpenDashboardConfig = OpenDashboardDefault & OpenDashboardOptional;
// @todo this actually returns type `Cypress.Chainable<OpenDashboardConfig>`
export const openDashboard = (config?: PartialOpenDashboardConfig) =>
getScenarioContext().then(({ lastAddedDashboardUid }: any) => { getScenarioContext().then(({ lastAddedDashboardUid }: any) => {
const fullConfig = { const fullConfig: OpenDashboardConfig = {
uid: lastAddedDashboardUid, uid: lastAddedDashboardUid,
...config, ...config,
} as OpenDashboardConfig; };
const { timeRange, uid } = fullConfig; const { timeRange, uid } = fullConfig;
......
...@@ -39,7 +39,7 @@ export const getScenarioContext = (): any => ...@@ -39,7 +39,7 @@ export const getScenarioContext = (): any =>
e2e() e2e()
.wrap( .wrap(
{ {
getScenarioContext: () => ({ ...scenarioContext } as ScenarioContext), getScenarioContext: (): ScenarioContext => ({ ...scenarioContext }),
}, },
{ log: false } { log: false }
) )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment