('kuery');
const { dataView } = useAlertsDataView({
featureIds,
http,
toasts,
- dataViewsService,
+ dataViewsService: dataService.dataViews,
});
const { aadFields, loading: fieldsLoading } = useRuleAADFields({
ruleTypeId,
@@ -119,7 +119,10 @@ export const AlertsSearchBar = ({
displayStyle: 'inPage',
showFilterBar,
onQuerySubmit: onSearchQuerySubmit,
- onFiltersUpdated,
+ onFiltersUpdated: (newFilters) => {
+ dataService.query.filterManager.setFilters(newFilters);
+ onFiltersUpdated?.(newFilters);
+ },
onRefresh,
showDatePicker,
showQueryInput: true,
diff --git a/packages/kbn-alerts-ui-shared/src/alerts_search_bar/types.ts b/packages/kbn-alerts-ui-shared/src/alerts_search_bar/types.ts
index 8875ef62947a8..f8566b2ec692c 100644
--- a/packages/kbn-alerts-ui-shared/src/alerts_search_bar/types.ts
+++ b/packages/kbn-alerts-ui-shared/src/alerts_search_bar/types.ts
@@ -11,7 +11,7 @@ import type { Filter } from '@kbn/es-query';
import type { ValidFeatureId } from '@kbn/rule-data-utils';
import type { ToastsStart, HttpStart } from '@kbn/core/public';
import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public';
-import type { DataViewsContract } from '@kbn/data-views-plugin/common';
+import { DataPublicPluginStart } from '@kbn/data-plugin/public';
export type QueryLanguageType = 'lucene' | 'kuery';
@@ -41,5 +41,5 @@ export interface AlertsSearchBarProps {
http: HttpStart;
toasts: ToastsStart;
unifiedSearchBar: UnifiedSearchPublicPluginStart['ui']['SearchBar'];
- dataViewsService: DataViewsContract;
+ dataService: DataPublicPluginStart;
}
diff --git a/packages/kbn-alerts-ui-shared/src/rule_form/rule_actions/rule_actions_alerts_filter.test.tsx b/packages/kbn-alerts-ui-shared/src/rule_form/rule_actions/rule_actions_alerts_filter.test.tsx
index d3ef68206cfa4..9b7502add4045 100644
--- a/packages/kbn-alerts-ui-shared/src/rule_form/rule_actions/rule_actions_alerts_filter.test.tsx
+++ b/packages/kbn-alerts-ui-shared/src/rule_form/rule_actions/rule_actions_alerts_filter.test.tsx
@@ -9,12 +9,12 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
import { httpServiceMock } from '@kbn/core/public/mocks';
-import { RuleActionsAlertsFilter } from './rule_actions_alerts_filter';
-import type { AlertsSearchBarProps } from '../../alerts_search_bar';
import { FilterStateStore } from '@kbn/es-query';
+import { AlertsSearchBarProps, AlertsSearchBar } from '../../alerts_search_bar';
import { getAction } from '../../common/test_utils/actions_test_utils';
-import userEvent from '@testing-library/user-event';
+import { RuleActionsAlertsFilter } from './rule_actions_alerts_filter';
const http = httpServiceMock.createStartContract();
@@ -23,43 +23,7 @@ jest.mock('../hooks', () => ({
}));
jest.mock('../../alerts_search_bar', () => ({
- AlertsSearchBar: ({ onFiltersUpdated, onQueryChange, onQuerySubmit }: AlertsSearchBarProps) => (
-
- AlertsSearchBar
-
-
-
-
- ),
+ AlertsSearchBar: jest.fn(),
}));
const { useRuleFormState } = jest.requireMock('../hooks');
@@ -79,7 +43,7 @@ describe('ruleActionsAlertsFilter', () => {
SearchBar: {},
},
},
- dataViews: {},
+ data: {},
},
formData: {
actions: [],
@@ -93,6 +57,46 @@ describe('ruleActionsAlertsFilter', () => {
});
});
+ (AlertsSearchBar as jest.Mock).mockImplementation(
+ ({ onFiltersUpdated, onQueryChange, onQuerySubmit }: AlertsSearchBarProps) => (
+
+ AlertsSearchBar
+
+
+
+
+ )
+ );
+
afterEach(() => {
jest.clearAllMocks();
});
@@ -166,18 +170,86 @@ describe('ruleActionsAlertsFilter', () => {
await userEvent.click(screen.getByText('Update Filter'));
expect(mockOnChange).toHaveBeenLastCalledWith({
- filters: [{ $state: { store: 'appState' }, meta: {} }],
+ filters: [{ $state: { store: 'appState' }, meta: {}, query: {} }],
kql: 'test',
});
await userEvent.click(screen.getByText('Update Query'));
expect(mockOnChange).toHaveBeenLastCalledWith({
- filters: [{ $state: { store: 'appState' }, meta: {} }],
+ filters: [{ $state: { store: 'appState' }, meta: {}, query: {} }],
kql: 'onQueryChange',
});
await userEvent.click(screen.getByText('Submit Query'));
expect(mockOnChange).toHaveBeenLastCalledWith({
- filters: [{ $state: { store: 'appState' }, meta: {} }],
+ filters: [{ $state: { store: 'appState' }, meta: {}, query: {} }],
kql: 'onQuerySubmit',
});
});
+
+ test('renders filters correctly', async () => {
+ const filters = [
+ {
+ meta: {
+ negate: false,
+ alias: null,
+ disabled: false,
+ type: 'custom',
+ key: 'query',
+ },
+ query: { bool: { filter: [{ term: { 'kibana.alert.rule.consumer': 'stackAlerts' } }] } },
+ $state: { store: FilterStateStore.APP_STATE },
+ },
+ ];
+
+ (AlertsSearchBar as jest.Mock).mockImplementation(
+ ({ onFiltersUpdated, onQueryChange, onQuerySubmit }: AlertsSearchBarProps) => (
+
+ AlertsSearchBar
+
+
+
+
+ )
+ );
+
+ render(
+
+ );
+
+ await userEvent.click(screen.getByTestId('alertsFilterQueryToggle'));
+
+ expect(mockOnChange).toHaveBeenLastCalledWith(undefined);
+
+ await userEvent.click(screen.getByText('Update Filter'));
+ expect(mockOnChange).toHaveBeenLastCalledWith({ filters, kql: '' });
+ });
});
diff --git a/packages/kbn-alerts-ui-shared/src/rule_form/rule_actions/rule_actions_alerts_filter.tsx b/packages/kbn-alerts-ui-shared/src/rule_form/rule_actions/rule_actions_alerts_filter.tsx
index 646d1b359969b..791c1ce0491f2 100644
--- a/packages/kbn-alerts-ui-shared/src/rule_form/rule_actions/rule_actions_alerts_filter.tsx
+++ b/packages/kbn-alerts-ui-shared/src/rule_form/rule_actions/rule_actions_alerts_filter.tsx
@@ -31,7 +31,7 @@ export interface RuleActionsAlertsFilterProps {
http: RuleFormPlugins['http'];
notifications: RuleFormPlugins['notifications'];
unifiedSearch: RuleFormPlugins['unifiedSearch'];
- dataViews: RuleFormPlugins['dataViews'];
+ data: RuleFormPlugins['data'];
};
}
@@ -48,7 +48,7 @@ export const RuleActionsAlertsFilter = ({
http,
notifications: { toasts },
unifiedSearch,
- dataViews,
+ data,
} = propsPlugins || plugins;
const [query, setQuery] = useState(action.alertsFilter?.query ?? DEFAULT_QUERY);
@@ -84,7 +84,19 @@ export const RuleActionsAlertsFilter = ({
);
const onFiltersUpdated = useCallback(
- (filters: Filter[]) => updateQuery({ filters }),
+ (filters: Filter[]) => {
+ const updatedFilters = filters.map((filter) => {
+ const { $state, meta, ...rest } = filter;
+ return {
+ $state,
+ meta,
+ query: filter?.query ? { ...filter.query } : { ...rest },
+ };
+ });
+
+ // Wrapping filters in query object here to avoid schema validation failure
+ updateQuery({ filters: updatedFilters });
+ },
[updateQuery]
);
@@ -108,7 +120,7 @@ export const RuleActionsAlertsFilter = ({
http={http}
toasts={toasts}
unifiedSearchBar={unifiedSearch.ui.SearchBar}
- dataViewsService={dataViews}
+ dataService={data}
appName={appName}
featureIds={featureIds}
ruleTypeId={ruleTypeId}
diff --git a/x-pack/plugins/alerting/public/pages/maintenance_windows/components/create_maintenance_windows_form.tsx b/x-pack/plugins/alerting/public/pages/maintenance_windows/components/create_maintenance_windows_form.tsx
index 6783289963f6c..7f3c25eeaf55d 100644
--- a/x-pack/plugins/alerting/public/pages/maintenance_windows/components/create_maintenance_windows_form.tsx
+++ b/x-pack/plugins/alerting/public/pages/maintenance_windows/components/create_maintenance_windows_form.tsx
@@ -117,6 +117,17 @@ export const CreateMaintenanceWindowForm = React.memo {
+ return filtersToTransform.map((filter) => {
+ const { $state, meta, ...rest } = filter;
+ return {
+ $state,
+ meta,
+ query: filter?.query ? { ...filter.query } : { ...rest },
+ };
+ });
+ };
+
const scopedQueryPayload = useMemo(() => {
if (!isScopedQueryEnabled) {
return null;
@@ -124,9 +135,13 @@ export const CreateMaintenanceWindowForm = React.memo
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/value_validators.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/value_validators.test.ts
index 97c9ba686435a..df1dce08f684a 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/lib/value_validators.test.ts
+++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/value_validators.test.ts
@@ -11,9 +11,10 @@ import {
isValidUrl,
getConnectorWithInvalidatedFields,
getRuleWithInvalidatedFields,
+ validateActionFilterQuery,
} from './value_validators';
import { v4 as uuidv4 } from 'uuid';
-import { Rule, IErrorObject, UserConfiguredActionConnector } from '../../types';
+import { Rule, IErrorObject, UserConfiguredActionConnector, RuleUiAction } from '../../types';
describe('throwIfAbsent', () => {
test('throws if value is absent', () => {
@@ -441,3 +442,70 @@ describe('getRuleWithInvalidatedFields', () => {
expect((rule.actions[1].params as any).incident.field.name).toEqual('myIncident');
});
});
+
+describe('validateActionFilterQuery', () => {
+ test('does not return an error when kql query exists', () => {
+ const actionItem: RuleUiAction = {
+ actionTypeId: 'test',
+ group: 'qwer',
+ id: '123',
+ params: {
+ incident: {
+ field: {
+ name: 'myIncident',
+ },
+ },
+ },
+ alertsFilter: { query: { kql: 'id: *', filters: [] } },
+ };
+
+ expect(validateActionFilterQuery(actionItem)).toBe(null);
+ });
+
+ test('does not return an error when filter query exists', () => {
+ const actionItem = {
+ actionTypeId: 'test',
+ group: 'qwer',
+ id: '123',
+ params: {
+ incident: {
+ field: {
+ name: 'myIncident',
+ },
+ },
+ },
+ alertsFilter: {
+ query: {
+ kql: undefined,
+ filters: [
+ {
+ $state: { store: 'state' },
+ meta: { key: 'test' },
+ query: { exists: { field: '_id' } },
+ },
+ ],
+ },
+ },
+ };
+
+ expect(validateActionFilterQuery(actionItem)).toBe(null);
+ });
+
+ test('returns an error no kql and no filters', () => {
+ const actionItem = {
+ actionTypeId: 'test',
+ group: 'qwer',
+ id: '123',
+ params: {
+ incident: {
+ field: {
+ name: 'myIncident',
+ },
+ },
+ },
+ alertsFilter: { query: { kql: '', filters: [] } },
+ };
+
+ expect(validateActionFilterQuery(actionItem)).toBe('A custom query is required.');
+ });
+});
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.tsx
index 9176d9d54ef3a..9af97b713dff3 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.tsx
+++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.tsx
@@ -157,7 +157,7 @@ export const ActionTypeForm = ({
http,
notifications,
unifiedSearch,
- dataViews,
+ data,
} = useKibana().services;
const { euiTheme } = useEuiTheme();
const [isOpen, setIsOpen] = useState(true);
@@ -513,7 +513,7 @@ export const ActionTypeForm = ({
plugins={{
http,
unifiedSearch,
- dataViews,
+ data,
notifications,
}}
/>
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_search_bar/alerts_search_bar.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_search_bar/alerts_search_bar.test.tsx
new file mode 100644
index 0000000000000..61fceacead341
--- /dev/null
+++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_search_bar/alerts_search_bar.test.tsx
@@ -0,0 +1,190 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import React from 'react';
+import { fireEvent, render, screen, waitFor } from '@testing-library/react';
+import { useAlertsDataView } from '@kbn/alerts-ui-shared/src/common/hooks/use_alerts_data_view';
+import { Filter, FilterStateStore } from '@kbn/es-query';
+import { dataPluginMock } from '@kbn/data-plugin/public/mocks';
+import { NotificationsStart } from '@kbn/core-notifications-browser';
+import { useKibana } from '@kbn/kibana-react-plugin/public';
+import { useLoadRuleTypesQuery } from '../../hooks/use_load_rule_types_query';
+import { useRuleAADFields } from '../../hooks/use_rule_aad_fields';
+import { AlertsSearchBar } from './alerts_search_bar';
+
+const mockDataPlugin = dataPluginMock.createStartContract();
+jest.mock('@kbn/kibana-utils-plugin/public');
+jest.mock('../../hooks/use_load_rule_types_query');
+jest.mock('../../hooks/use_rule_aad_fields');
+jest.mock('@kbn/alerts-ui-shared/src/common/hooks/use_alerts_data_view');
+jest.mock('@kbn/kibana-react-plugin/public', () => ({
+ ...jest.requireActual('@kbn/kibana-react-plugin/public'),
+ useKibana: jest.fn(),
+}));
+
+jest.mocked(useAlertsDataView).mockReturnValue({
+ isLoading: false,
+ dataView: {
+ title: '.alerts-*',
+ fields: [
+ {
+ name: 'event.action',
+ type: 'string',
+ aggregatable: true,
+ searchable: true,
+ },
+ ],
+ },
+});
+
+jest.mocked(useLoadRuleTypesQuery).mockReturnValue({
+ ruleTypesState: {
+ initialLoad: false,
+ data: new Map(),
+ isLoading: false,
+ error: undefined,
+ },
+ authorizedToReadAnyRules: false,
+ hasAnyAuthorizedRuleType: false,
+ authorizedRuleTypes: [],
+ authorizedToCreateAnyRules: false,
+ isSuccess: false,
+});
+
+jest.mocked(useRuleAADFields).mockReturnValue({
+ aadFields: [],
+ loading: false,
+});
+
+const mockUseKibana = useKibana as jest.Mock;
+
+describe('AlertsSearchBar', () => {
+ beforeEach(() => {
+ mockUseKibana.mockReturnValue({
+ services: {
+ data: mockDataPlugin,
+ unifiedSearch: {
+ ui: {
+ SearchBar: jest.fn().mockImplementation((props) => (
+
+ )),
+ },
+ },
+ notifications: { toasts: { addWarning: jest.fn() } } as unknown as NotificationsStart,
+ },
+ });
+ });
+
+ beforeEach(() => {
+ jest.clearAllMocks();
+ });
+
+ it('renders correctly', async () => {
+ render(
+
+ );
+ expect(await screen.findByTestId('querySubmitButton')).toBeInTheDocument();
+ });
+
+ it('calls onQuerySubmit correctly', async () => {
+ const onQuerySubmitMock = jest.fn();
+
+ render(
+
+ );
+
+ fireEvent.click(await screen.findByTestId('querySubmitButton'));
+
+ await waitFor(() => {
+ expect(onQuerySubmitMock).toHaveBeenCalled();
+ });
+ });
+
+ it('calls onFiltersUpdated correctly', async () => {
+ const onFiltersUpdatedMock = jest.fn();
+ const filters: Filter[] = [
+ {
+ meta: {
+ negate: false,
+ alias: null,
+ disabled: false,
+ type: 'custom',
+ key: 'query',
+ },
+ query: { bool: { filter: [{ term: { 'kibana.alert.rule.consumer': 'stackAlerts' } }] } },
+ $state: { store: FilterStateStore.APP_STATE },
+ },
+ ];
+
+ mockUseKibana.mockReturnValue({
+ services: {
+ data: mockDataPlugin,
+ unifiedSearch: {
+ ui: {
+ SearchBar: jest.fn().mockImplementation((props) => (
+
+ )),
+ },
+ },
+ notifications: { toasts: { addWarning: jest.fn() } } as unknown as NotificationsStart,
+ },
+ });
+
+ render(
+
+ );
+
+ fireEvent.click(await screen.findByTestId('filtersSubmitButton'));
+
+ await waitFor(() => {
+ expect(onFiltersUpdatedMock).toHaveBeenCalledWith(filters);
+ expect(mockDataPlugin.query.filterManager.setFilters).toHaveBeenCalledWith(filters);
+ });
+ });
+});
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_search_bar/alerts_search_bar.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_search_bar/alerts_search_bar.tsx
index 3896e5d0e938a..5e2880e65231c 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_search_bar/alerts_search_bar.tsx
+++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_search_bar/alerts_search_bar.tsx
@@ -53,6 +53,7 @@ export function AlertsSearchBar({
unifiedSearch: {
ui: { SearchBar },
},
+ data: dataService,
} = useKibana().services;
const [queryLanguage, setQueryLanguage] = useState('kuery');
@@ -183,7 +184,11 @@ export function AlertsSearchBar({
displayStyle="inPage"
showFilterBar={showFilterBar}
onQuerySubmit={onSearchQuerySubmit}
- onFiltersUpdated={onFiltersUpdated}
+ onFiltersUpdated={(newFilters) => {
+ const mappedFilters = structuredClone(newFilters);
+ dataService.query.filterManager.setFilters(mappedFilters);
+ onFiltersUpdated?.(mappedFilters);
+ }}
onRefresh={onRefresh}
showDatePicker={showDatePicker}
showQueryInput={true}
diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/alert_create_flyout.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/alert_create_flyout.ts
index bf4a81ea4772d..3c39bd235bf97 100644
--- a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/alert_create_flyout.ts
+++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/alert_create_flyout.ts
@@ -25,6 +25,8 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
const toasts = getService('toasts');
const esClient = getService('es');
const apmSynthtraceKibanaClient = getService('apmSynthtraceKibanaClient');
+ const filterBar = getService('filterBar');
+ const esArchiver = getService('esArchiver');
async function getAlertsByName(name: string) {
const {
@@ -95,6 +97,9 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
describe('create alert', function () {
let apmSynthtraceEsClient: ApmSynthtraceEsClient;
before(async () => {
+ await esArchiver.load(
+ 'test/api_integration/fixtures/es_archiver/index_patterns/constant_keyword'
+ );
const version = (await apmSynthtraceKibanaClient.installApmPackage()).version;
apmSynthtraceEsClient = await getApmSynthtraceEsClient({
client: esClient,
@@ -130,7 +135,12 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
return Promise.all([apmSynthtraceEsClient.index(events)]);
});
- after(() => apmSynthtraceEsClient.clean());
+ after(async () => {
+ await apmSynthtraceEsClient.clean();
+ await esArchiver.unload(
+ 'test/api_integration/fixtures/es_archiver/index_patterns/constant_keyword'
+ );
+ });
beforeEach(async () => {
await pageObjects.common.navigateToApp('triggersActions');
@@ -344,6 +354,57 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
await deleteAlerts(alertsToDelete.map((alertItem: { id: string }) => alertItem.id));
});
+ it('should create an alert with DSL filter for conditional action', async () => {
+ const alertName = generateUniqueKey();
+ await rules.common.defineIndexThresholdAlert(alertName);
+
+ // filterKuery validation
+ await testSubjects.setValue('filterKuery', 'group:');
+ const filterKueryInput = await testSubjects.find('filterKuery');
+ expect(await filterKueryInput.elementHasClass('euiFieldSearch-isInvalid')).to.eql(true);
+ await testSubjects.setValue('filterKuery', 'group: group-0');
+ expect(await filterKueryInput.elementHasClass('euiFieldSearch-isInvalid')).to.eql(false);
+
+ await testSubjects.click('.slack-alerting-ActionTypeSelectOption');
+ await testSubjects.click('addNewActionConnectorButton-.slack');
+ const slackConnectorName = generateUniqueKey();
+ await testSubjects.setValue('nameInput', slackConnectorName);
+ await testSubjects.setValue('slackWebhookUrlInput', 'https://test.com');
+ await find.clickByCssSelector('[data-test-subj="saveActionButtonModal"]:not(disabled)');
+ const createdConnectorToastTitle = await toasts.getTitleAndDismiss();
+ expect(createdConnectorToastTitle).to.eql(`Created '${slackConnectorName}'`);
+ await testSubjects.click('notifyWhenSelect');
+ await testSubjects.click('onThrottleInterval');
+ await testSubjects.setValue('throttleInput', '10');
+
+ await testSubjects.click('alertsFilterQueryToggle');
+
+ await pageObjects.header.waitUntilLoadingHasFinished();
+
+ const filter = `{
+ "bool": {
+ "filter": [{ "term": { "kibana.alert.rule.consumer": "*" } }]
+ }
+ }`;
+ await filterBar.addDslFilter(filter, true);
+
+ await testSubjects.click('saveRuleButton');
+
+ const toastTitle = await toasts.getTitleAndDismiss();
+ expect(toastTitle).to.eql(`Created rule "${alertName}"`);
+
+ await testSubjects.click('editActionHoverButton');
+ await pageObjects.header.waitUntilLoadingHasFinished();
+
+ await testSubjects.scrollIntoView('globalQueryBar');
+
+ await filterBar.hasFilter('query', filter, true);
+
+ // clean up created alert
+ const alertsToDelete = await getAlertsByName(alertName);
+ await deleteAlerts(alertsToDelete.map((alertItem: { id: string }) => alertItem.id));
+ });
+
it('should create an alert with actions in multiple groups', async () => {
const alertName = generateUniqueKey();
await defineAlwaysFiringAlert(alertName);
@@ -542,5 +603,34 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
await deleteConnectorByName('webhook-test');
});
+
+ it('should add filter', async () => {
+ const ruleName = generateUniqueKey();
+ await defineAlwaysFiringAlert(ruleName);
+
+ await testSubjects.click('saveRuleButton');
+ await testSubjects.existOrFail('confirmRuleSaveModal');
+ await testSubjects.click('confirmRuleSaveModal > confirmModalConfirmButton');
+ await testSubjects.missingOrFail('confirmRuleSaveModal');
+
+ const toastTitle = await toasts.getTitleAndDismiss();
+ expect(toastTitle).to.eql(`Created rule "${ruleName}"`);
+
+ await testSubjects.click('triggersActionsAlerts');
+
+ const filter = `{
+ "bool": {
+ "filter": [{ "term": { "kibana.alert.rule.name": "${ruleName}" } }]
+ }
+ }`;
+
+ await filterBar.addDslFilter(filter, true);
+
+ await filterBar.hasFilter('query', filter, true);
+
+ // clean up created alert
+ const alertsToDelete = await getAlertsByName(ruleName);
+ await deleteAlerts(alertsToDelete.map((alertItem: { id: string }) => alertItem.id));
+ });
});
};