Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[8.x] [Observability] add custom threshold functional test (#184602) #193248

Merged
merged 1 commit into from
Sep 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ export function MetricRowWithAgg({
}
>
<EuiExpression
data-test-subj="aggregationName"
data-test-subj={`aggregationName${name}`}
description={aggregationTypes[aggType].text}
value={aggType === Aggregators.COUNT ? filter || DEFAULT_COUNT_FILTER_TITLE : field}
isActive={aggTypePopoverOpen}
Expand Down Expand Up @@ -228,6 +228,7 @@ export function MetricRowWithAgg({
options={fieldOptions}
selectedOptions={field ? [{ label: field }] : []}
onChange={handleFieldChange}
data-test-subj="aggregationField"
/>
</EuiFormRow>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ export const ExpressionRow: React.FC<ExpressionRowProps> = (props) => {
<EuiFlexItem>
<EuiFormRow label={LABEL_LABEL} fullWidth helpText={LABEL_HELP_MESSAGE}>
<EuiFieldText
data-test-subj="thresholdRuleCustomEquationEditorFieldText"
data-test-subj="thresholdRuleCustomEquationEditorFieldTextLabel"
compressed
fullWidth
value={label}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,18 @@ import { EuiPopoverTitle, EuiFlexGroup, EuiFlexItem, EuiButtonIcon } from '@elas
interface ClosablePopoverTitleProps {
children: JSX.Element;
onClose: () => void;
dataTestSubj?: string;
}

export const ClosablePopoverTitle = ({ children, onClose }: ClosablePopoverTitleProps) => {
export const ClosablePopoverTitle = ({
children,
onClose,
dataTestSubj,
}: ClosablePopoverTitleProps) => {
return (
<EuiPopoverTitle>
<EuiFlexGroup alignItems="center" gutterSize="s">
<EuiFlexItem>{children}</EuiFlexItem>
<EuiFlexItem data-test-subj={dataTestSubj}>{children}</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButtonIcon
iconType="cross"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,10 @@ describe('threshold expression', () => {

wrapper.find('[data-test-subj="thresholdPopover"]').last().simulate('click');
expect(wrapper.find('[data-test-subj="comparatorOptionsComboBox"]').exists()).toBeTruthy();
expect(wrapper.find('[data-test-subj="alertThresholdInput"]').exists()).toBeTruthy();
expect(wrapper.find('[data-test-subj="alertThresholdInput0"]').exists()).toBeTruthy();

wrapper
.find('[data-test-subj="alertThresholdInput"]')
.find('[data-test-subj="alertThresholdInput0"]')
.last()
.simulate('change', { target: { value: 1000 } });
expect(onChangeSelectedThreshold).toHaveBeenCalled();
Expand Down Expand Up @@ -145,21 +145,22 @@ describe('threshold expression', () => {

wrapper.find('[data-test-subj="thresholdPopover"]').last().simulate('click');
expect(wrapper.find('[data-test-subj="comparatorOptionsComboBox"]').exists()).toBeTruthy();
expect(wrapper.find('input[data-test-subj="alertThresholdInput"]').length).toEqual(1);
expect(wrapper.find('input[data-test-subj="alertThresholdInput0"]').length).toEqual(1);

wrapper
.find('[data-test-subj="comparatorOptionsComboBox"]')
.last()
.simulate('change', { target: { value: 'between' } });
wrapper.update();
expect(wrapper.find('input[data-test-subj="alertThresholdInput"]').length).toEqual(2);
expect(wrapper.find('input[data-test-subj="alertThresholdInput0"]').length).toEqual(1);
expect(wrapper.find('input[data-test-subj="alertThresholdInput1"]').length).toEqual(1);

wrapper
.find('[data-test-subj="comparatorOptionsComboBox"]')
.last()
.simulate('change', { target: { value: '<' } });
wrapper.update();
expect(wrapper.find('input[data-test-subj="alertThresholdInput"]').length).toEqual(1);
expect(wrapper.find('input[data-test-subj="alertThresholdInput0"]').length).toEqual(1);
});

it('is valid when the threshold value is 0', () => {
Expand All @@ -174,9 +175,9 @@ describe('threshold expression', () => {
onChangeSelectedThresholdComparator={onChangeSelectedThresholdComparator}
/>
);
expect(wrapper.find('[data-test-subj="alertThresholdInput"]')).toMatchInlineSnapshot(`
expect(wrapper.find('[data-test-subj="alertThresholdInput0"]')).toMatchInlineSnapshot(`
<EuiFieldNumber
data-test-subj="alertThresholdInput"
data-test-subj="alertThresholdInput0"
isInvalid={false}
min={0}
onChange={[Function]}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,10 @@ export const ThresholdExpression = ({
repositionOnScroll
>
<div>
<ClosablePopoverTitle onClose={() => setAlertThresholdPopoverOpen(false)}>
<ClosablePopoverTitle
onClose={() => setAlertThresholdPopoverOpen(false)}
dataTestSubj="thresholdPopoverTitle"
>
<>{comparators[comparator].text}</>
</ClosablePopoverTitle>
<EuiFlexGroup>
Expand Down Expand Up @@ -154,7 +157,7 @@ export const ThresholdExpression = ({
error={errors[`threshold${i}`] as string[]}
>
<EuiFieldNumber
data-test-subj="alertThresholdInput"
data-test-subj={`alertThresholdInput${i}`}
min={0}
value={!threshold || threshold[i] === undefined ? '' : threshold[i]}
isInvalid={Number(errors[`threshold${i}`]?.length) > 0 || isNil(threshold[i])}
Expand Down
67 changes: 67 additions & 0 deletions x-pack/test/functional/services/observability/alerts/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
*/

import expect from '@kbn/expect';
import { ToolingLog } from '@kbn/tooling-log';
import { chunk } from 'lodash';
import { ALERT_STATUS_ACTIVE, ALERT_STATUS_RECOVERED, AlertStatus } from '@kbn/rule-data-utils';
import { WebElementWrapper } from '@kbn/ftr-common-functional-ui-services';
import { Agent as SuperTestAgent } from 'supertest';
import { FtrProviderContext } from '../../../ftr_provider_context';

// Based on the x-pack/test/functional/es_archives/observability/alerts archive.
Expand Down Expand Up @@ -314,6 +316,69 @@ export function ObservabilityAlertsCommonProvider({
return value;
});

// Data view
const createDataView = async ({
supertest,
id,
name,
title,
logger,
}: {
supertest: SuperTestAgent;
id: string;
name: string;
title: string;
logger: ToolingLog;
}) => {
const { body } = await supertest
.post(`/api/content_management/rpc/create`)
.set('kbn-xsrf', 'foo')
.send({
contentTypeId: 'index-pattern',
data: {
fieldAttrs: '{}',
title,
timeFieldName: '@timestamp',
sourceFilters: '[]',
fields: '[]',
fieldFormatMap: '{}',
typeMeta: '{}',
runtimeFieldMap: '{}',
name,
},
options: { id },
version: 1,
})
.expect(200);

logger.debug(`Created data view: ${JSON.stringify(body)}`);
return body;
};

const deleteDataView = async ({
supertest,
id,
logger,
}: {
supertest: SuperTestAgent;
id: string;
logger: ToolingLog;
}) => {
const { body } = await supertest
.post(`/api/content_management/rpc/delete`)
.set('kbn-xsrf', 'foo')
.send({
contentTypeId: 'index-pattern',
id,
options: { force: true },
version: 1,
})
.expect(200);

logger.debug(`Deleted data view id: ${id}`);
return body;
};

return {
getQueryBar,
clearQueryBar,
Expand Down Expand Up @@ -357,5 +422,7 @@ export function ObservabilityAlertsCommonProvider({
navigateToRulesLogsPage,
navigateToRuleDetailsByRuleId,
navigateToAlertDetails,
createDataView,
deleteDataView,
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import { FtrProviderContext } from '../../../ftr_provider_context';

const METRIC_THRESHOLD_RULE_TYPE_SELECTOR = 'metrics.alert.threshold-SelectOption';
const CUSTOM_THRESHOLD_RULE_TYPE_SELECTOR = 'observability.rules.custom_threshold-SelectOption';

export function ObservabilityAlertsRulesProvider({ getService }: FtrProviderContext) {
const testSubjects = getService('testSubjects');
Expand All @@ -18,8 +19,9 @@ export function ObservabilityAlertsRulesProvider({ getService }: FtrProviderCont
};

const clickCreateRuleButton = async () => {
await testSubjects.existOrFail('createRuleButton');
const createRuleButton = await testSubjects.find('createRuleButton');
return createRuleButton.click();
return await createRuleButton.click();
};

const clickRuleStatusDropDownMenu = async () => testSubjects.click('statusDropdown');
Expand All @@ -33,6 +35,7 @@ export function ObservabilityAlertsRulesProvider({ getService }: FtrProviderCont
};

const clickOnInfrastructureCategory = async () => {
await testSubjects.existOrFail('ruleTypeModal');
const categories = await testSubjects.find('ruleTypeModal');
const category = await categories.findByCssSelector(`.euiFacetButton[title="Infrastructure"]`);
await category.click();
Expand All @@ -43,6 +46,18 @@ export function ObservabilityAlertsRulesProvider({ getService }: FtrProviderCont
await testSubjects.click(METRIC_THRESHOLD_RULE_TYPE_SELECTOR);
};

const clickOnObservabilityCategory = async () => {
await testSubjects.existOrFail('ruleTypeModal');
const categories = await testSubjects.find('ruleTypeModal');
const category = await categories.findByCssSelector(`.euiFacetButton[title="Observability"]`);
await category.click();
};

const clickOnCustomThresholdRule = async () => {
await testSubjects.existOrFail(CUSTOM_THRESHOLD_RULE_TYPE_SELECTOR);
await testSubjects.click(CUSTOM_THRESHOLD_RULE_TYPE_SELECTOR);
};

return {
getManageRulesPageHref,
clickCreateRuleButton,
Expand All @@ -52,5 +67,7 @@ export function ObservabilityAlertsRulesProvider({ getService }: FtrProviderCont
clickOnRuleInEventLogs,
clickOnInfrastructureCategory,
clickOnMetricThresholdRule,
clickOnObservabilityCategory,
clickOnCustomThresholdRule,
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
return ruleName === alertName;
});
await testSubjects.click('thresholdPopover');
await testSubjects.setValue('alertThresholdInput', '1');
await testSubjects.setValue('alertThresholdInput0', '1');

await testSubjects.click('forLastExpression');
await testSubjects.setValue('timeWindowSizeNumber', '30');
Expand Down Expand Up @@ -469,7 +469,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await filterBar.addFilter({ field: 'message.keyword', operation: 'is', value: 'msg-1' });

await testSubjects.click('thresholdPopover');
await testSubjects.setValue('alertThresholdInput', '1');
await testSubjects.setValue('alertThresholdInput0', '1');
await testSubjects.click('saveEditedRuleButton');
await PageObjects.header.waitUntilLoadingHasFinished();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export default function ({ loadTestFile }: FtrProviderContext) {
loadTestFile(require.resolve('./pages/alerts/rule_stats'));
loadTestFile(require.resolve('./pages/alerts/state_synchronization'));
loadTestFile(require.resolve('./pages/alerts/table_storage'));
loadTestFile(require.resolve('./pages/alerts/custom_threshold'));
loadTestFile(require.resolve('./pages/cases/case_details'));
loadTestFile(require.resolve('./pages/overview/alert_table'));
loadTestFile(require.resolve('./exploratory_view'));
Expand Down
Loading