mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Azure Monitor: E2E Tests (#54619)
* Update credentials form with data-testids and aria-labels * Update gitignore * Add example dashboard * Stub out E2E test for creating ds and importing dashboard * Add component selectors * Remove subscription check temporarily * Appropriately set disabled prop * Fix lint issues * Update to use selectors and wait on subscriptions request * Add test for metrics panel - Add required selectors for resource picker and metrics query editor * Add logs and ARG basic query scenarios - More selector updates * Add E2E test for template variables - Tests advanced resource picker - Adds required selectors * Remove log and add annotation e2e test * Update test * Prettier/betterer updates - Remove gitignore change * Lint issues * Update betterer results * Lint issue and remove unneeded import * Don't print certain commands * Avoiding flakiness - Ensure code editor has sufficient time to load in ARG test - Avoid flakiness around correct template variable being selected by typing in resource name * Remove be.visible requirement * Update test * Update selector name * Reuse datasource * Fix datasource reuse and combine query tests * Remove import dashboard step as unneeded * Review - Randomise datasource name - Skip annotations test - Remove unused example dashboard * Update to ensure e2e test works in CI * Update e2e test - Update environment variables (process is not available in cypress) - Add wait on resource picker searches to avoid flakiness - Update subscription and resource group names * Update CODEOWNERS * Parse credentials in CI from outputs file * Update outputs file path * Fix selector * Undo selector change * Update e2e tests - Set default subscription - Fix datasource selection in variable editor - Fix resource picker search flakiness - Set subscription in ARG query test - Fix resource group selection - Update resource group * Review * Review 2
This commit is contained in:
parent
aa9039a841
commit
7bb76e0975
1
.github/CODEOWNERS
vendored
1
.github/CODEOWNERS
vendored
@ -118,6 +118,7 @@ go.sum @grafana/backend-platform
|
||||
/public/locales @grafana/user-essentials
|
||||
/public/app/core/internationalization @grafana/user-essentials
|
||||
/e2e @grafana/user-essentials
|
||||
/e2e/cloud-plugins-suite @grafana/cloud-provider-plugins
|
||||
/packages @grafana/user-essentials @grafana/plugins-platform-frontend @grafana/grafana-bi-squad
|
||||
/packages/grafana-e2e-selectors @grafana/user-essentials
|
||||
/packages/grafana-e2e @grafana/user-essentials
|
||||
|
298
e2e/cloud-plugins-suite/azure-monitor.spec.ts
Normal file
298
e2e/cloud-plugins-suite/azure-monitor.spec.ts
Normal file
@ -0,0 +1,298 @@
|
||||
import { load } from 'js-yaml';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
import { e2e } from '@grafana/e2e';
|
||||
|
||||
import { selectors } from '../../public/app/plugins/datasource/grafana-azure-monitor-datasource/e2e/selectors';
|
||||
import {
|
||||
AzureDataSourceJsonData,
|
||||
AzureDataSourceSecureJsonData,
|
||||
AzureQueryType,
|
||||
} from '../../public/app/plugins/datasource/grafana-azure-monitor-datasource/types';
|
||||
|
||||
const provisioningPath = `../../provisioning/datasources/azmonitor-ds.yaml`;
|
||||
const e2eSelectors = e2e.getSelectors(selectors.components);
|
||||
|
||||
type AzureMonitorConfig = {
|
||||
secureJsonData: AzureDataSourceSecureJsonData;
|
||||
jsonData: AzureDataSourceJsonData;
|
||||
};
|
||||
|
||||
type AzureMonitorProvision = { datasources: AzureMonitorConfig[] };
|
||||
|
||||
const dataSourceName = `Azure Monitor E2E Tests - ${uuidv4()}`;
|
||||
|
||||
function provisionAzureMonitorDatasources(datasources: AzureMonitorProvision[]) {
|
||||
const datasource = datasources[0].datasources[0];
|
||||
|
||||
e2e()
|
||||
.intercept(/subscriptions/)
|
||||
.as('subscriptions');
|
||||
|
||||
e2e.flows.addDataSource({
|
||||
type: 'Azure Monitor',
|
||||
name: dataSourceName,
|
||||
form: () => {
|
||||
e2eSelectors.configEditor.azureCloud.input().find('input').type('Azure').type('{enter}');
|
||||
// We set the log value to false here to ensure that secrets aren't printed to logs
|
||||
e2eSelectors.configEditor.tenantID.input().find('input').type(datasource.jsonData.tenantId, { log: false });
|
||||
e2eSelectors.configEditor.clientID.input().find('input').type(datasource.jsonData.clientId, { log: false });
|
||||
e2eSelectors.configEditor.clientSecret
|
||||
.input()
|
||||
.find('input')
|
||||
.type(datasource.secureJsonData.clientSecret, { log: false });
|
||||
e2eSelectors.configEditor.loadSubscriptions.button().click().wait('@subscriptions').wait(500);
|
||||
e2eSelectors.configEditor.defaultSubscription.input().find('input').type('datasources{enter}');
|
||||
},
|
||||
expectedAlertMessage: 'Successfully connected to all Azure Monitor endpoints',
|
||||
});
|
||||
}
|
||||
|
||||
const addAzureMonitorVariable = (
|
||||
name: string,
|
||||
type: AzureQueryType,
|
||||
isFirst: boolean,
|
||||
options?: { subscription?: string; resourceGroup?: string; namespace?: string; resource?: string }
|
||||
) => {
|
||||
e2e.components.PageToolbar.item('Dashboard settings').click();
|
||||
e2e.components.Tab.title('Variables').click();
|
||||
if (isFirst) {
|
||||
e2e.pages.Dashboard.Settings.Variables.List.addVariableCTAV2().click();
|
||||
} else {
|
||||
e2e.pages.Dashboard.Settings.Variables.List.newButton().click();
|
||||
}
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.General.generalNameInputV2().clear().type(name);
|
||||
e2e.components.DataSourcePicker.inputV2().type(`${dataSourceName}{enter}`);
|
||||
e2eSelectors.variableEditor.queryType
|
||||
.input()
|
||||
.find('input')
|
||||
.type(`${type.replace('Azure', '').trim()}{enter}`);
|
||||
switch (type) {
|
||||
case AzureQueryType.ResourceGroupsQuery:
|
||||
e2eSelectors.variableEditor.subscription.input().find('input').type(`${options?.subscription}{enter}`);
|
||||
break;
|
||||
case AzureQueryType.NamespacesQuery:
|
||||
e2eSelectors.variableEditor.subscription.input().find('input').type(`${options?.subscription}{enter}`);
|
||||
e2eSelectors.variableEditor.resourceGroup.input().find('input').type(`${options?.resourceGroup}{enter}`);
|
||||
break;
|
||||
case AzureQueryType.ResourceNamesQuery:
|
||||
e2eSelectors.variableEditor.subscription.input().find('input').type(`${options?.subscription}{enter}`);
|
||||
e2eSelectors.variableEditor.resourceGroup.input().find('input').type(`${options?.resourceGroup}{enter}`);
|
||||
e2eSelectors.variableEditor.namespace.input().find('input').type(`${options?.namespace}{enter}`);
|
||||
break;
|
||||
case AzureQueryType.MetricNamesQuery:
|
||||
e2eSelectors.variableEditor.subscription.input().find('input').type(`${options?.subscription}{enter}`);
|
||||
e2eSelectors.variableEditor.resourceGroup.input().find('input').type(`${options?.resourceGroup}{enter}`);
|
||||
e2eSelectors.variableEditor.namespace.input().find('input').type(`${options?.namespace}{enter}`);
|
||||
e2eSelectors.variableEditor.resource.input().find('input').type(`${options?.resource}{enter}`);
|
||||
break;
|
||||
}
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.General.submitButton().click();
|
||||
e2e.components.PageToolbar.item('Go Back').click();
|
||||
};
|
||||
|
||||
e2e.scenario({
|
||||
describeName: 'Add Azure Monitor datasource',
|
||||
itName: 'fills out datasource connection configuration',
|
||||
scenario: () => {
|
||||
// This variable will be set in CI
|
||||
const CI = e2e.env('CI');
|
||||
if (CI) {
|
||||
e2e()
|
||||
.readFile('../../outputs.json')
|
||||
.then((outputs) => {
|
||||
provisionAzureMonitorDatasources([
|
||||
{
|
||||
datasources: [
|
||||
{
|
||||
jsonData: {
|
||||
cloudName: 'Azure',
|
||||
tenantId: outputs.tenantId,
|
||||
clientId: outputs.clientId,
|
||||
},
|
||||
secureJsonData: { clientSecret: outputs.clientSecret },
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
});
|
||||
} else {
|
||||
e2e()
|
||||
.readFile(provisioningPath)
|
||||
.then((azMonitorProvision: string) => {
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||
const yaml = load(azMonitorProvision) as AzureMonitorProvision;
|
||||
provisionAzureMonitorDatasources([yaml]);
|
||||
});
|
||||
}
|
||||
e2e.setScenarioContext({ addedDataSources: [] });
|
||||
},
|
||||
});
|
||||
|
||||
e2e.scenario({
|
||||
describeName: 'Create dashboard and add a panel for each query type',
|
||||
itName: 'create dashboard, add panel for metrics query, log analytics query, and ARG query',
|
||||
scenario: () => {
|
||||
e2e.flows.addDashboard({
|
||||
timeRange: {
|
||||
from: '2022-10-03 00:00:00',
|
||||
to: '2022-10-03 23:59:59',
|
||||
zone: 'Coordinated Universal Time',
|
||||
},
|
||||
});
|
||||
e2e.flows.addPanel({
|
||||
dataSourceName,
|
||||
visitDashboardAtStart: false,
|
||||
queriesForm: () => {
|
||||
e2eSelectors.queryEditor.resourcePicker.select.button().click();
|
||||
e2eSelectors.queryEditor.resourcePicker.search
|
||||
.input()
|
||||
.wait(100)
|
||||
.type('azmonmetricstest')
|
||||
.wait(500)
|
||||
.type('{enter}');
|
||||
e2e().contains('azmonmetricstest').click();
|
||||
e2eSelectors.queryEditor.resourcePicker.apply.button().click();
|
||||
e2e().contains('microsoft.storage/storageaccounts');
|
||||
e2eSelectors.queryEditor.metricsQueryEditor.metricName.input().find('input').type('Used capacity{enter}');
|
||||
},
|
||||
});
|
||||
e2e.components.PanelEditor.applyButton().click();
|
||||
e2e.flows.addPanel({
|
||||
dataSourceName,
|
||||
visitDashboardAtStart: false,
|
||||
queriesForm: () => {
|
||||
e2eSelectors.queryEditor.header.select().find('input').type('Logs{enter}');
|
||||
e2eSelectors.queryEditor.resourcePicker.select.button().click();
|
||||
e2eSelectors.queryEditor.resourcePicker.search
|
||||
.input()
|
||||
.wait(100)
|
||||
.type('azmonlogstest')
|
||||
.wait(500)
|
||||
.type('{enter}');
|
||||
e2e().contains('azmonlogstest').click();
|
||||
e2eSelectors.queryEditor.resourcePicker.apply.button().click();
|
||||
e2e.components.CodeEditor.container().type('AzureDiagnostics');
|
||||
e2eSelectors.queryEditor.logsQueryEditor.formatSelection.input().type('Time series{enter}');
|
||||
},
|
||||
});
|
||||
e2e.components.PanelEditor.applyButton().click();
|
||||
e2e.flows.addPanel({
|
||||
dataSourceName,
|
||||
visitDashboardAtStart: false,
|
||||
queriesForm: () => {
|
||||
e2eSelectors.queryEditor.header.select().find('input').type('Azure Resource Graph{enter}');
|
||||
e2e().wait(1000); // Need to wait for code editor to completely load
|
||||
e2e().get('[aria-label="Remove Primary Subscription"]').click();
|
||||
e2eSelectors.queryEditor.argsQueryEditor.subscriptions.input().find('input').type('datasources{enter}');
|
||||
e2e.components.CodeEditor.container().type(
|
||||
"Resources | where resourceGroup == 'cloud-plugins-e2e-test' | project name, resourceGroup"
|
||||
);
|
||||
e2e.components.PanelEditor.toggleTableView().click({ force: true });
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
e2e.scenario({
|
||||
describeName: 'Create dashboard with template variables',
|
||||
itName: 'creates a dashboard that includes a template variable',
|
||||
scenario: () => {
|
||||
e2e.flows.addDashboard({
|
||||
timeRange: {
|
||||
from: '2022-10-03 00:00:00',
|
||||
to: '2022-10-03 23:59:59',
|
||||
zone: 'Coordinated Universal Time',
|
||||
},
|
||||
});
|
||||
addAzureMonitorVariable('subscription', AzureQueryType.SubscriptionsQuery, true);
|
||||
addAzureMonitorVariable('resourceGroups', AzureQueryType.ResourceGroupsQuery, false, {
|
||||
subscription: '$subscription',
|
||||
});
|
||||
addAzureMonitorVariable('namespaces', AzureQueryType.NamespacesQuery, false, {
|
||||
subscription: '$subscription',
|
||||
resourceGroup: '$resourceGroups',
|
||||
});
|
||||
addAzureMonitorVariable('resource', AzureQueryType.ResourceNamesQuery, false, {
|
||||
subscription: '$subscription',
|
||||
resourceGroup: '$resourceGroups',
|
||||
namespace: '$namespace',
|
||||
});
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemLabels('subscription').click();
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('grafanalabs-datasources-dev').click();
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemLabels('resourceGroups').parent().find('button').click();
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemLabels('resourceGroups')
|
||||
.parent()
|
||||
.find('input')
|
||||
.type('cloud-plugins-e2e-test{enter}');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemLabels('namespaces').parent().find('button').click();
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemLabels('namespaces')
|
||||
.parent()
|
||||
.find('input')
|
||||
.type('microsoft.storage/storageaccounts{enter}');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemLabels('resource').parent().find('button').click();
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemLabels('resource').parent().find('input').type('azmonmetricstest{enter}');
|
||||
e2e.flows.addPanel({
|
||||
dataSourceName,
|
||||
visitDashboardAtStart: false,
|
||||
queriesForm: () => {
|
||||
e2eSelectors.queryEditor.resourcePicker.select.button().click();
|
||||
e2eSelectors.queryEditor.resourcePicker.advanced.collapse().click();
|
||||
e2eSelectors.queryEditor.resourcePicker.advanced.subscription.input().find('input').type('$subscription');
|
||||
e2eSelectors.queryEditor.resourcePicker.advanced.resourceGroup.input().find('input').type('$resourceGroups');
|
||||
e2eSelectors.queryEditor.resourcePicker.advanced.namespace.input().find('input').type('$namespaces');
|
||||
e2eSelectors.queryEditor.resourcePicker.advanced.resource.input().find('input').type('$resource');
|
||||
e2eSelectors.queryEditor.resourcePicker.apply.button().click();
|
||||
e2eSelectors.queryEditor.metricsQueryEditor.metricName.input().find('input').type('Transactions{enter}');
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
e2e.scenario({
|
||||
describeName: 'Create dashboard with annotation',
|
||||
itName: 'creates a dashboard that includes an annotation',
|
||||
scenario: () => {
|
||||
e2e.flows.addDashboard({
|
||||
timeRange: {
|
||||
from: '2022-10-03 00:00:00',
|
||||
to: '2022-10-03 23:59:59',
|
||||
zone: 'Coordinated Universal Time',
|
||||
},
|
||||
});
|
||||
e2e.components.PageToolbar.item('Dashboard settings').click();
|
||||
e2e.components.Tab.title('Annotations').click();
|
||||
e2e.pages.Dashboard.Settings.Annotations.List.addAnnotationCTAV2().click();
|
||||
e2e.pages.Dashboard.Settings.Annotations.Settings.name().type('TestAnnotation');
|
||||
e2e.components.DataSourcePicker.inputV2().click().type(`${dataSourceName}{enter}`);
|
||||
e2eSelectors.queryEditor.resourcePicker.select.button().click();
|
||||
e2eSelectors.queryEditor.resourcePicker.search.input().type('azmonmetricstest');
|
||||
e2e().contains('azmonmetricstest').click();
|
||||
e2eSelectors.queryEditor.resourcePicker.apply.button().click();
|
||||
e2e().contains('microsoft.storage/storageaccounts');
|
||||
e2eSelectors.queryEditor.metricsQueryEditor.metricName.input().find('input').type('Transactions{enter}');
|
||||
e2e().get('table').contains('text').parent().find('input').click().type('Transactions (number){enter}');
|
||||
e2e.components.PageToolbar.item('Go Back').click();
|
||||
e2e.flows.addPanel({
|
||||
dataSourceName,
|
||||
visitDashboardAtStart: false,
|
||||
queriesForm: () => {
|
||||
e2eSelectors.queryEditor.resourcePicker.select.button().click();
|
||||
e2eSelectors.queryEditor.resourcePicker.search.input().type('azmonmetricstest');
|
||||
e2e().contains('azmonmetricstest').click();
|
||||
e2eSelectors.queryEditor.resourcePicker.apply.button().click();
|
||||
e2e().contains('microsoft.storage/storageaccounts');
|
||||
e2eSelectors.queryEditor.metricsQueryEditor.metricName.input().find('input').type('Used capacity{enter}');
|
||||
},
|
||||
});
|
||||
},
|
||||
skipScenario: true,
|
||||
});
|
||||
|
||||
e2e.scenario({
|
||||
describeName: 'Remove datasource',
|
||||
itName: 'remove azure monitor datasource',
|
||||
scenario: () => {
|
||||
e2e.flows.deleteDataSource({ name: dataSourceName, id: '', quick: true });
|
||||
},
|
||||
});
|
@ -148,7 +148,7 @@ export const configurePanel = (config: PartialAddPanelConfig | PartialEditPanelC
|
||||
//e2e().wait('@chartData');
|
||||
|
||||
// Avoid annotations flakiness
|
||||
e2e.components.RefreshPicker.runButtonV2().first().should('be.visible').click({ force: true });
|
||||
e2e.components.RefreshPicker.runButtonV2().first().click({ force: true });
|
||||
|
||||
e2e().wait('@chartData');
|
||||
|
||||
|
@ -3,6 +3,7 @@ import React from 'react';
|
||||
|
||||
import createMockDatasource from '../../__mocks__/datasource';
|
||||
import createMockQuery from '../../__mocks__/query';
|
||||
import { selectors } from '../../e2e/selectors';
|
||||
|
||||
import ArgQueryEditor from './ArgQueryEditor';
|
||||
|
||||
@ -31,7 +32,9 @@ const defaultProps = {
|
||||
describe('ArgQueryEditor', () => {
|
||||
it('should render', async () => {
|
||||
render(<ArgQueryEditor {...defaultProps} />);
|
||||
expect(await screen.findByTestId('azure-monitor-arg-query-editor-with-experimental-ui')).toBeInTheDocument();
|
||||
expect(
|
||||
await screen.findByTestId(selectors.components.queryEditor.argsQueryEditor.container.input)
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should select a subscription from the fetched array', async () => {
|
||||
@ -40,7 +43,9 @@ describe('ArgQueryEditor', () => {
|
||||
});
|
||||
const onChange = jest.fn();
|
||||
render(<ArgQueryEditor {...defaultProps} datasource={datasource} onChange={onChange} />);
|
||||
expect(await screen.findByTestId('azure-monitor-arg-query-editor-with-experimental-ui')).toBeInTheDocument();
|
||||
expect(
|
||||
await screen.findByTestId(selectors.components.queryEditor.argsQueryEditor.container.input)
|
||||
).toBeInTheDocument();
|
||||
expect(onChange).toHaveBeenCalledWith(expect.objectContaining({ subscriptions: ['foo'] }));
|
||||
});
|
||||
|
||||
@ -50,7 +55,9 @@ describe('ArgQueryEditor', () => {
|
||||
subscriptions: ['bar'],
|
||||
});
|
||||
render(<ArgQueryEditor {...defaultProps} onChange={onChange} query={query} />);
|
||||
expect(await screen.findByTestId('azure-monitor-arg-query-editor-with-experimental-ui')).toBeInTheDocument();
|
||||
expect(
|
||||
await screen.findByTestId(selectors.components.queryEditor.argsQueryEditor.container.input)
|
||||
).toBeInTheDocument();
|
||||
expect(onChange).toHaveBeenCalledWith(expect.objectContaining({ subscriptions: ['bar'] }));
|
||||
});
|
||||
|
||||
@ -63,7 +70,9 @@ describe('ArgQueryEditor', () => {
|
||||
subscriptions: ['bar'],
|
||||
});
|
||||
render(<ArgQueryEditor {...defaultProps} datasource={datasource} onChange={onChange} query={query} />);
|
||||
expect(await screen.findByTestId('azure-monitor-arg-query-editor-with-experimental-ui')).toBeInTheDocument();
|
||||
expect(
|
||||
await screen.findByTestId(selectors.components.queryEditor.argsQueryEditor.container.input)
|
||||
).toBeInTheDocument();
|
||||
expect(onChange).toHaveBeenCalledWith(expect.objectContaining({ subscriptions: ['foo'] }));
|
||||
expect(onChange).not.toHaveBeenCalledWith(expect.objectContaining({ subscriptions: ['bar'] }));
|
||||
});
|
||||
@ -77,7 +86,9 @@ describe('ArgQueryEditor', () => {
|
||||
subscriptions: ['foo', 'bar', 'foobar'],
|
||||
});
|
||||
render(<ArgQueryEditor {...defaultProps} datasource={datasource} onChange={onChange} query={query} />);
|
||||
expect(await screen.findByTestId('azure-monitor-arg-query-editor-with-experimental-ui')).toBeInTheDocument();
|
||||
expect(
|
||||
await screen.findByTestId(selectors.components.queryEditor.argsQueryEditor.container.input)
|
||||
).toBeInTheDocument();
|
||||
expect(onChange).toHaveBeenCalledWith(expect.objectContaining({ subscriptions: ['foo', 'bar'] }));
|
||||
expect(onChange).not.toHaveBeenCalledWith(expect.objectContaining({ subscriptions: ['foo', 'bar', 'foobar'] }));
|
||||
});
|
||||
|
@ -4,6 +4,7 @@ import React, { useState, useMemo } from 'react';
|
||||
import { EditorFieldGroup, EditorRow, EditorRows } from '@grafana/experimental';
|
||||
|
||||
import Datasource from '../../datasource';
|
||||
import { selectors } from '../../e2e/selectors';
|
||||
import { AzureMonitorErrorish, AzureMonitorOption, AzureMonitorQuery } from '../../types';
|
||||
import SubscriptionField from '../SubscriptionField';
|
||||
|
||||
@ -73,7 +74,7 @@ const ArgQueryEditor: React.FC<ArgQueryEditorProps> = ({
|
||||
}, [datasource]);
|
||||
|
||||
return (
|
||||
<span data-testid="azure-monitor-arg-query-editor-with-experimental-ui">
|
||||
<span data-testid={selectors.components.queryEditor.argsQueryEditor.container.input}>
|
||||
<EditorRows>
|
||||
<EditorRow>
|
||||
<EditorFieldGroup>
|
||||
|
@ -1,10 +1,12 @@
|
||||
import React, { ChangeEvent, FunctionComponent, useEffect, useReducer, useState } from 'react';
|
||||
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { InlineFormLabel, LegacyForms, Button, Select } from '@grafana/ui';
|
||||
import { InlineFormLabel, LegacyForms, Button, Select, InlineField } from '@grafana/ui';
|
||||
|
||||
import { isCredentialsComplete } from '../credentials';
|
||||
import { selectors } from '../e2e/selectors';
|
||||
import { AzureAuthType, AzureCredentials } from '../types';
|
||||
|
||||
const { Input } = LegacyForms;
|
||||
|
||||
export interface Props {
|
||||
@ -28,6 +30,8 @@ const authTypeOptions: Array<SelectableValue<AzureAuthType>> = [
|
||||
},
|
||||
];
|
||||
|
||||
const LABEL_WIDTH = 18;
|
||||
|
||||
export const AzureCredentialsForm: FunctionComponent<Props> = (props: Props) => {
|
||||
const { credentials, azureCloudOptions, onCredentialsChange, getSubscriptions, disabled } = props;
|
||||
const hasRequiredFields = isCredentialsComplete(credentials);
|
||||
@ -153,68 +157,77 @@ export const AzureCredentialsForm: FunctionComponent<Props> = (props: Props) =>
|
||||
return (
|
||||
<div className="gf-form-group">
|
||||
{props.managedIdentityEnabled && (
|
||||
<div className="gf-form-inline">
|
||||
<div className="gf-form">
|
||||
<InlineFormLabel className="width-12" tooltip="Choose the type of authentication to Azure services">
|
||||
Authentication
|
||||
</InlineFormLabel>
|
||||
<Select
|
||||
className="width-15"
|
||||
value={authTypeOptions.find((opt) => opt.value === credentials.authType)}
|
||||
options={authTypeOptions}
|
||||
onChange={onAuthTypeChange}
|
||||
disabled={disabled}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<InlineField
|
||||
label="Authentication"
|
||||
labelWidth={LABEL_WIDTH}
|
||||
tooltip="Choose the type of authentication to Azure services"
|
||||
data-testid={selectors.components.configEditor.authType.select}
|
||||
htmlFor="authentication-type"
|
||||
>
|
||||
<Select
|
||||
className="width-15"
|
||||
value={authTypeOptions.find((opt) => opt.value === credentials.authType)}
|
||||
options={authTypeOptions}
|
||||
onChange={onAuthTypeChange}
|
||||
disabled={disabled}
|
||||
/>
|
||||
</InlineField>
|
||||
)}
|
||||
{credentials.authType === 'clientsecret' && (
|
||||
<>
|
||||
{azureCloudOptions && (
|
||||
<div className="gf-form-inline">
|
||||
<div className="gf-form">
|
||||
<InlineFormLabel className="width-12" tooltip="Choose an Azure Cloud">
|
||||
Azure Cloud
|
||||
</InlineFormLabel>
|
||||
<Select
|
||||
aria-label="Azure Cloud"
|
||||
className="width-15"
|
||||
value={azureCloudOptions.find((opt) => opt.value === credentials.azureCloud)}
|
||||
options={azureCloudOptions}
|
||||
onChange={onAzureCloudChange}
|
||||
disabled={disabled}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<InlineField
|
||||
label="Azure Cloud"
|
||||
labelWidth={LABEL_WIDTH}
|
||||
tooltip="Choose an Azure Cloud"
|
||||
data-testid={selectors.components.configEditor.azureCloud.input}
|
||||
htmlFor="azure-cloud-type"
|
||||
disabled={disabled}
|
||||
>
|
||||
<Select
|
||||
inputId="azure-cloud-type"
|
||||
aria-label="Azure Cloud"
|
||||
className="width-15"
|
||||
value={azureCloudOptions.find((opt) => opt.value === credentials.azureCloud)}
|
||||
options={azureCloudOptions}
|
||||
onChange={onAzureCloudChange}
|
||||
/>
|
||||
</InlineField>
|
||||
)}
|
||||
<div className="gf-form-inline">
|
||||
<div className="gf-form">
|
||||
<InlineFormLabel className="width-12">Directory (tenant) ID</InlineFormLabel>
|
||||
<div className="width-15">
|
||||
<Input
|
||||
className="width-30"
|
||||
placeholder="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
|
||||
value={credentials.tenantId || ''}
|
||||
onChange={onTenantIdChange}
|
||||
disabled={disabled}
|
||||
/>
|
||||
</div>
|
||||
<InlineField
|
||||
label="Directory (tenant) ID"
|
||||
labelWidth={LABEL_WIDTH}
|
||||
data-testid={selectors.components.configEditor.tenantID.input}
|
||||
htmlFor="tenant-id"
|
||||
>
|
||||
<div className="width-15">
|
||||
<Input
|
||||
aria-label="Tenant ID"
|
||||
className="width-30"
|
||||
placeholder="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
|
||||
value={credentials.tenantId || ''}
|
||||
onChange={onTenantIdChange}
|
||||
disabled={disabled}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="gf-form-inline">
|
||||
<div className="gf-form">
|
||||
<InlineFormLabel className="width-12">Application (client) ID</InlineFormLabel>
|
||||
<div className="width-15">
|
||||
<Input
|
||||
className="width-30"
|
||||
placeholder="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
|
||||
value={credentials.clientId || ''}
|
||||
onChange={onClientIdChange}
|
||||
disabled={disabled}
|
||||
/>
|
||||
</div>
|
||||
</InlineField>
|
||||
<InlineField
|
||||
label="Application (client) ID"
|
||||
labelWidth={LABEL_WIDTH}
|
||||
data-testid={selectors.components.configEditor.clientID.input}
|
||||
htmlFor="tenant-id"
|
||||
>
|
||||
<div className="width-15">
|
||||
<Input
|
||||
className="width-30"
|
||||
aria-label="Client ID"
|
||||
placeholder="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
|
||||
value={credentials.clientId || ''}
|
||||
onChange={onClientIdChange}
|
||||
disabled={disabled}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</InlineField>
|
||||
{!disabled &&
|
||||
(typeof credentials.clientSecret === 'symbol' ? (
|
||||
<div className="gf-form-inline">
|
||||
@ -231,27 +244,28 @@ export const AzureCredentialsForm: FunctionComponent<Props> = (props: Props) =>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="gf-form-inline">
|
||||
<div className="gf-form">
|
||||
<InlineFormLabel className="width-12">Client Secret</InlineFormLabel>
|
||||
<div className="width-15">
|
||||
<Input
|
||||
className="width-30"
|
||||
placeholder="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
|
||||
value={credentials.clientSecret || ''}
|
||||
onChange={onClientSecretChange}
|
||||
disabled={disabled}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<InlineField
|
||||
label="Client Secret"
|
||||
labelWidth={LABEL_WIDTH}
|
||||
data-testid={selectors.components.configEditor.clientSecret.input}
|
||||
htmlFor="client-secret"
|
||||
>
|
||||
<Input
|
||||
className="width-30"
|
||||
aria-label="Client Secret"
|
||||
placeholder="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
|
||||
value={credentials.clientSecret || ''}
|
||||
onChange={onClientSecretChange}
|
||||
disabled={disabled}
|
||||
/>
|
||||
</InlineField>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
{getSubscriptions && (
|
||||
<>
|
||||
<div className="gf-form-inline">
|
||||
<div className="gf-form">
|
||||
<div className="gf-form" data-testid={selectors.components.configEditor.defaultSubscription.input}>
|
||||
<InlineFormLabel className="width-12">Default Subscription</InlineFormLabel>
|
||||
<div className="width-30">
|
||||
<Select
|
||||
@ -274,10 +288,12 @@ export const AzureCredentialsForm: FunctionComponent<Props> = (props: Props) =>
|
||||
<div className="max-width-30 gf-form-inline">
|
||||
<Button
|
||||
variant="secondary"
|
||||
aria-label="Load Subscriptions"
|
||||
size="sm"
|
||||
type="button"
|
||||
onClick={onLoadSubscriptions}
|
||||
disabled={!hasRequiredFields}
|
||||
data-testid={selectors.components.configEditor.loadSubscriptions.button}
|
||||
>
|
||||
Load Subscriptions
|
||||
</Button>
|
||||
|
@ -3,6 +3,7 @@ import React, { useCallback, useMemo } from 'react';
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { Select } from '@grafana/ui';
|
||||
|
||||
import { selectors } from '../../e2e/selectors';
|
||||
import { AzureQueryEditorFieldProps } from '../../types';
|
||||
import { Field } from '../Field';
|
||||
|
||||
@ -30,7 +31,7 @@ const FormatAsField: React.FC<AzureQueryEditorFieldProps> = ({ query, variableOp
|
||||
);
|
||||
|
||||
return (
|
||||
<Field label="Format as">
|
||||
<Field label="Format as" data-testid={selectors.components.queryEditor.logsQueryEditor.formatSelection.input}>
|
||||
<Select
|
||||
inputId="azure-monitor-logs-workspaces-field"
|
||||
value={query.azureLogAnalytics?.resultFormat}
|
||||
|
@ -3,6 +3,7 @@ import React, { useCallback, useMemo } from 'react';
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { Select } from '@grafana/ui';
|
||||
|
||||
import { selectors } from '../../e2e/selectors';
|
||||
import { AzureQueryEditorFieldProps, AzureMonitorOption } from '../../types';
|
||||
import { Field } from '../Field';
|
||||
|
||||
@ -28,7 +29,7 @@ const MetricNameField: React.FC<MetricNameProps> = ({ metricNames, query, variab
|
||||
const options = useMemo(() => [...metricNames, variableOptionGroup], [metricNames, variableOptionGroup]);
|
||||
|
||||
return (
|
||||
<Field label="Metric">
|
||||
<Field label="Metric" data-testid={selectors.components.queryEditor.metricsQueryEditor.metricName.input}>
|
||||
<Select
|
||||
inputId="azure-monitor-metrics-metric-field"
|
||||
value={query.azureMonitor?.metricName ?? null}
|
||||
|
@ -83,6 +83,8 @@ describe('Azure Monitor QueryEditor', () => {
|
||||
|
||||
render(<QueryEditor query={mockQuery} datasource={mockDatasource} onChange={() => {}} onRunQuery={() => {}} />);
|
||||
|
||||
await waitFor(() => expect(screen.getByTestId('azure-monitor-experimental-header')).toBeInTheDocument());
|
||||
await waitFor(() =>
|
||||
expect(screen.getByTestId('data-testid azure-monitor-experimental-header')).toBeInTheDocument()
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@ -3,6 +3,7 @@ import React, { useCallback } from 'react';
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { EditorHeader, InlineSelect } from '@grafana/experimental';
|
||||
|
||||
import { selectors } from '../e2e/selectors';
|
||||
import { AzureMonitorQuery, AzureQueryType } from '../types';
|
||||
|
||||
interface QueryTypeFieldProps {
|
||||
@ -29,7 +30,7 @@ export const QueryHeader: React.FC<QueryTypeFieldProps> = ({ query, onQueryChang
|
||||
);
|
||||
|
||||
return (
|
||||
<span data-testid="azure-monitor-experimental-header">
|
||||
<span data-testid={selectors.components.queryEditor.header.select}>
|
||||
<EditorHeader>
|
||||
<InlineSelect
|
||||
label="Service"
|
||||
|
@ -4,6 +4,7 @@ import React, { useCallback, useEffect, useState } from 'react';
|
||||
import { Button, Icon, Modal, useStyles2 } from '@grafana/ui';
|
||||
|
||||
import Datasource from '../../datasource';
|
||||
import { selectors } from '../../e2e/selectors';
|
||||
import { ResourcePickerQueryType } from '../../resourcePicker/resourcePickerData';
|
||||
import { AzureQueryEditorFieldProps, AzureMetricResource } from '../../types';
|
||||
import { Field } from '../Field';
|
||||
@ -50,7 +51,7 @@ const ResourceField: React.FC<ResourceFieldProps<string | AzureMetricResource>>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<span data-testid={selectors.components.queryEditor.resourcePicker.select.button}>
|
||||
<Modal
|
||||
className={styles.modal}
|
||||
title="Select a resource"
|
||||
@ -74,7 +75,7 @@ const ResourceField: React.FC<ResourceFieldProps<string | AzureMetricResource>>
|
||||
<ResourceLabel resource={resource} datasource={datasource} />
|
||||
</Button>
|
||||
</Field>
|
||||
</>
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -2,6 +2,7 @@ import React, { useState } from 'react';
|
||||
|
||||
import { Icon, Input, Tooltip, Collapse, Label, InlineField } from '@grafana/ui';
|
||||
|
||||
import { selectors } from '../../e2e/selectors';
|
||||
import { AzureMetricResource } from '../../types';
|
||||
import { Space } from '../Space';
|
||||
|
||||
@ -14,7 +15,7 @@ const Advanced = ({ resource, onChange }: ResourcePickerProps<string | AzureMetr
|
||||
const [isAdvancedOpen, setIsAdvancedOpen] = useState(!!resource && JSON.stringify(resource).includes('$'));
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div data-testid={selectors.components.queryEditor.resourcePicker.advanced.collapse}>
|
||||
<Collapse
|
||||
collapsible
|
||||
label="Advanced"
|
||||
@ -63,6 +64,7 @@ const Advanced = ({ resource, onChange }: ResourcePickerProps<string | AzureMetr
|
||||
transparent
|
||||
htmlFor="input-advanced-resource-picker-subscription"
|
||||
labelWidth={15}
|
||||
data-testid={selectors.components.queryEditor.resourcePicker.advanced.subscription.input}
|
||||
>
|
||||
<Input
|
||||
id="input-advanced-resource-picker-subscription"
|
||||
@ -77,6 +79,7 @@ const Advanced = ({ resource, onChange }: ResourcePickerProps<string | AzureMetr
|
||||
transparent
|
||||
htmlFor="input-advanced-resource-picker-resourceGroup"
|
||||
labelWidth={15}
|
||||
data-testid={selectors.components.queryEditor.resourcePicker.advanced.resourceGroup.input}
|
||||
>
|
||||
<Input
|
||||
id="input-advanced-resource-picker-resourceGroup"
|
||||
@ -91,6 +94,7 @@ const Advanced = ({ resource, onChange }: ResourcePickerProps<string | AzureMetr
|
||||
transparent
|
||||
htmlFor="input-advanced-resource-picker-metricNamespace"
|
||||
labelWidth={15}
|
||||
data-testid={selectors.components.queryEditor.resourcePicker.advanced.namespace.input}
|
||||
>
|
||||
<Input
|
||||
id="input-advanced-resource-picker-metricNamespace"
|
||||
@ -105,6 +109,7 @@ const Advanced = ({ resource, onChange }: ResourcePickerProps<string | AzureMetr
|
||||
transparent
|
||||
htmlFor="input-advanced-resource-picker-resourceName"
|
||||
labelWidth={15}
|
||||
data-testid={selectors.components.queryEditor.resourcePicker.advanced.resource.input}
|
||||
>
|
||||
<Input
|
||||
id="input-advanced-resource-picker-resourceName"
|
||||
|
@ -4,6 +4,7 @@ import { useEffectOnce } from 'react-use';
|
||||
|
||||
import { Alert, Button, LoadingPlaceholder, useStyles2 } from '@grafana/ui';
|
||||
|
||||
import { selectors } from '../../e2e/selectors';
|
||||
import ResourcePickerData, { ResourcePickerQueryType } from '../../resourcePicker/resourcePickerData';
|
||||
import { AzureMetricResource } from '../../types';
|
||||
import messageFromError from '../../utils/messageFromError';
|
||||
@ -232,7 +233,11 @@ const ResourcePicker = ({
|
||||
<Advanced resource={internalSelected} onChange={(r) => setInternalSelected(r)} />
|
||||
<Space v={2} />
|
||||
|
||||
<Button disabled={!!errorMessage} onClick={handleApply}>
|
||||
<Button
|
||||
disabled={!!errorMessage}
|
||||
onClick={handleApply}
|
||||
data-testid={selectors.components.queryEditor.resourcePicker.apply.button}
|
||||
>
|
||||
Apply
|
||||
</Button>
|
||||
|
||||
|
@ -3,6 +3,8 @@ import React, { useEffect, useMemo, useState } from 'react';
|
||||
|
||||
import { Icon, Input } from '@grafana/ui';
|
||||
|
||||
import { selectors } from '../../e2e/selectors';
|
||||
|
||||
const Search = ({ searchFn }: { searchFn: (searchPhrase: string) => void }) => {
|
||||
const [searchFilter, setSearchFilter] = useState('');
|
||||
|
||||
@ -25,6 +27,7 @@ const Search = ({ searchFn }: { searchFn: (searchPhrase: string) => void }) => {
|
||||
debouncedSearch(searchPhrase);
|
||||
}}
|
||||
placeholder="search for a resource"
|
||||
data-testid={selectors.components.queryEditor.resourcePicker.search.input}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
@ -3,6 +3,7 @@ import React, { useCallback, useMemo } from 'react';
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { Select, MultiSelect } from '@grafana/ui';
|
||||
|
||||
import { selectors } from '../e2e/selectors';
|
||||
import { AzureMonitorQuery, AzureQueryEditorFieldProps, AzureMonitorOption, AzureQueryType } from '../types';
|
||||
import { findOptions } from '../utils/common';
|
||||
|
||||
@ -67,7 +68,7 @@ const SubscriptionField: React.FC<SubscriptionFieldProps> = ({
|
||||
const options = useMemo(() => [...subscriptions, variableOptionGroup], [subscriptions, variableOptionGroup]);
|
||||
|
||||
return multiSelect ? (
|
||||
<Field label="Subscriptions">
|
||||
<Field label="Subscriptions" data-testid={selectors.components.queryEditor.argsQueryEditor.subscriptions.input}>
|
||||
<MultiSelect
|
||||
isClearable
|
||||
value={findOptions([...subscriptions, ...variableOptionGroup.options], query.subscriptions)}
|
||||
@ -78,7 +79,7 @@ const SubscriptionField: React.FC<SubscriptionFieldProps> = ({
|
||||
/>
|
||||
</Field>
|
||||
) : (
|
||||
<Field label="Subscription">
|
||||
<Field label="Subscription" data-testid={selectors.components.queryEditor.argsQueryEditor.subscriptions.input}>
|
||||
<Select
|
||||
value={query.subscription}
|
||||
inputId="azure-monitor-subscriptions-field"
|
||||
|
@ -6,6 +6,7 @@ import { SelectableValue } from '@grafana/data';
|
||||
import { Alert, InlineField, Select } from '@grafana/ui';
|
||||
|
||||
import DataSource from '../../datasource';
|
||||
import { selectors } from '../../e2e/selectors';
|
||||
import { migrateQuery } from '../../grafanaTemplateVariableFns';
|
||||
import { AzureMonitorOption, AzureMonitorQuery, AzureQueryType } from '../../types';
|
||||
import useLastError from '../../utils/useLastError';
|
||||
@ -201,7 +202,11 @@ const VariableEditor = (props: Props) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<InlineField label="Select query type" labelWidth={20}>
|
||||
<InlineField
|
||||
label="Select query type"
|
||||
labelWidth={20}
|
||||
data-testid={selectors.components.variableEditor.queryType.input}
|
||||
>
|
||||
<Select
|
||||
aria-label="select query type"
|
||||
onChange={onQueryTypeChange}
|
||||
@ -235,7 +240,11 @@ const VariableEditor = (props: Props) => {
|
||||
<GrafanaTemplateVariableFnInput query={query} updateQuery={props.onChange} datasource={datasource} />
|
||||
)}
|
||||
{requireSubscription && (
|
||||
<InlineField label="Select subscription" labelWidth={20}>
|
||||
<InlineField
|
||||
label="Select subscription"
|
||||
labelWidth={20}
|
||||
data-testid={selectors.components.variableEditor.subscription.input}
|
||||
>
|
||||
<Select
|
||||
aria-label="select subscription"
|
||||
onChange={onChangeSubscription}
|
||||
@ -246,7 +255,11 @@ const VariableEditor = (props: Props) => {
|
||||
</InlineField>
|
||||
)}
|
||||
{(requireResourceGroup || hasResourceGroup) && (
|
||||
<InlineField label="Select resource group" labelWidth={20}>
|
||||
<InlineField
|
||||
label="Select resource group"
|
||||
labelWidth={20}
|
||||
data-testid={selectors.components.variableEditor.resourceGroup.input}
|
||||
>
|
||||
<Select
|
||||
aria-label="select resource group"
|
||||
onChange={onChangeResourceGroup}
|
||||
@ -262,7 +275,11 @@ const VariableEditor = (props: Props) => {
|
||||
</InlineField>
|
||||
)}
|
||||
{(requireNamespace || hasNamespace) && (
|
||||
<InlineField label="Select namespace" labelWidth={20}>
|
||||
<InlineField
|
||||
label="Select namespace"
|
||||
labelWidth={20}
|
||||
data-testid={selectors.components.variableEditor.namespace.input}
|
||||
>
|
||||
<Select
|
||||
aria-label="select namespace"
|
||||
onChange={onChangeNamespace}
|
||||
@ -278,7 +295,11 @@ const VariableEditor = (props: Props) => {
|
||||
</InlineField>
|
||||
)}
|
||||
{requireResource && (
|
||||
<InlineField label="Select resource" labelWidth={20}>
|
||||
<InlineField
|
||||
label="Select resource"
|
||||
labelWidth={20}
|
||||
data-testid={selectors.components.variableEditor.resource.input}
|
||||
>
|
||||
<Select
|
||||
aria-label="select resource"
|
||||
onChange={onChangeResource}
|
||||
|
@ -0,0 +1,100 @@
|
||||
import { E2ESelectors } from '@grafana/e2e-selectors';
|
||||
|
||||
export const components = {
|
||||
configEditor: {
|
||||
authType: {
|
||||
select: 'data-testid auth-type',
|
||||
},
|
||||
azureCloud: {
|
||||
input: 'data-testid azure-cloud',
|
||||
},
|
||||
tenantID: {
|
||||
input: 'data-testid tenant-id',
|
||||
},
|
||||
clientID: {
|
||||
input: 'data-testid client-id',
|
||||
},
|
||||
clientSecret: {
|
||||
input: 'data-testid client-secret',
|
||||
},
|
||||
loadSubscriptions: {
|
||||
button: 'data-testid load-subscriptions',
|
||||
},
|
||||
defaultSubscription: {
|
||||
input: 'data-testid default-subscription',
|
||||
},
|
||||
},
|
||||
queryEditor: {
|
||||
header: {
|
||||
select: 'data-testid azure-monitor-experimental-header',
|
||||
},
|
||||
resourcePicker: {
|
||||
select: {
|
||||
button: 'data-testid resource-picker-select',
|
||||
},
|
||||
search: {
|
||||
input: 'data-testid resource-picker-search',
|
||||
},
|
||||
apply: {
|
||||
button: 'data-testid resource-picker-apply',
|
||||
},
|
||||
cancel: {
|
||||
button: 'data-testid resource-picker-cancel',
|
||||
},
|
||||
advanced: {
|
||||
collapse: 'data-testid resource-picker-advanced',
|
||||
subscription: {
|
||||
input: 'data-testid resource-picker-subscription',
|
||||
},
|
||||
resourceGroup: {
|
||||
input: 'data-testid resource-picker-resource-group',
|
||||
},
|
||||
namespace: {
|
||||
input: 'data-testid resource-picker-namespace',
|
||||
},
|
||||
resource: {
|
||||
input: 'data-testid resource-picker-resource',
|
||||
},
|
||||
},
|
||||
},
|
||||
metricsQueryEditor: {
|
||||
metricName: {
|
||||
input: 'data-testid metric-name',
|
||||
},
|
||||
},
|
||||
logsQueryEditor: {
|
||||
formatSelection: {
|
||||
input: 'data-testid format-selection',
|
||||
},
|
||||
},
|
||||
argsQueryEditor: {
|
||||
container: {
|
||||
input: 'data-testid azure-monitor-arg-query-editor',
|
||||
},
|
||||
subscriptions: {
|
||||
input: 'data-testid azure-monitor-args-subscription',
|
||||
},
|
||||
},
|
||||
},
|
||||
variableEditor: {
|
||||
queryType: {
|
||||
input: 'data-testid query-type',
|
||||
},
|
||||
subscription: {
|
||||
input: 'data-testid subscription',
|
||||
},
|
||||
resourceGroup: {
|
||||
input: 'data-testid resource-group',
|
||||
},
|
||||
namespace: {
|
||||
input: 'data-testid namespace',
|
||||
},
|
||||
resource: {
|
||||
input: 'data-testid resource',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const selectors: { components: E2ESelectors<typeof components> } = {
|
||||
components: components,
|
||||
};
|
Loading…
Reference in New Issue
Block a user