[RAM] Create serverless functional tests for rule details (#168101)

Serverless functional tests for rule details on Search.

I did not copy all rule details tests to serverless. Some of them will
be copied after soon rules changes:
https://github.com/elastic/kibana/issues/168965

---------

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Julia 2023-10-23 22:28:10 +02:00 committed by GitHub
parent 1659434b94
commit c2e4d40a23
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 795 additions and 1 deletions

View file

@ -17,6 +17,7 @@ import { SvlObltOverviewPageProvider } from './svl_oblt_overview_page';
import { SvlSearchLandingPageProvider } from './svl_search_landing_page';
import { SvlSecLandingPageProvider } from './svl_sec_landing_page';
import { SvlTriggersActionsPageProvider } from './svl_triggers_actions_ui_page';
import { SvlRuleDetailsPageProvider } from './svl_rule_details_ui_page';
export const pageObjects = {
...xpackFunctionalPageObjects,
@ -30,4 +31,5 @@ export const pageObjects = {
svlSearchLandingPage: SvlSearchLandingPageProvider,
svlSecLandingPage: SvlSecLandingPageProvider,
svlTriggersActionsUI: SvlTriggersActionsPageProvider,
svlRuleDetailsUI: SvlRuleDetailsPageProvider,
};

View file

@ -0,0 +1,123 @@
/*
* 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 expect from '@kbn/expect';
import { FtrProviderContext } from '../ftr_provider_context';
export function SvlRuleDetailsPageProvider({ getService }: FtrProviderContext) {
const testSubjects = getService('testSubjects');
const find = getService('find');
const log = getService('log');
const retry = getService('retry');
return {
async getHeadingText() {
return await testSubjects.getVisibleText('ruleDetailsTitle');
},
async getRuleType() {
return await testSubjects.getVisibleText('ruleTypeLabel');
},
async getAPIKeyOwner() {
return await testSubjects.getVisibleText('apiKeyOwnerLabel');
},
async getAlertsList() {
const table = await find.byCssSelector(
'.euiBasicTable[data-test-subj="alertsList"]:not(.euiBasicTable-loading)'
);
const $ = await table.parseDomContent();
return $.findTestSubjects('alert-row')
.toArray()
.map((row) => {
return {
alert: $(row)
.findTestSubject('alertsTableCell-alert')
.find('.euiTableCellContent')
.text(),
status: $(row)
.findTestSubject('alertsTableCell-status')
.find('.euiTableCellContent')
.text(),
start: $(row)
.findTestSubject('alertsTableCell-start')
.find('.euiTableCellContent')
.text(),
duration: $(row)
.findTestSubject('alertsTableCell-duration')
.find('.euiTableCellContent')
.text(),
};
});
},
async getAlertDurationEpoch(): Promise<number> {
const alertDurationEpoch = await find.byCssSelector(
'input[data-test-subj="alertsDurationEpoch"]'
);
return parseInt(await alertDurationEpoch.getAttribute('value'), 10);
},
async clickAlertMuteButton(alert: string) {
const muteAlertButton = await testSubjects.find(`muteAlertButton_${alert}`);
await muteAlertButton.click();
},
async ensureAlertMuteState(alert: string, isMuted: boolean) {
await retry.try(async () => {
const muteAlertButton = await testSubjects.find(`muteAlertButton_${alert}`);
log.debug(`checked:${await muteAlertButton.getAttribute('aria-checked')}`);
expect(await muteAlertButton.getAttribute('aria-checked')).to.eql(
isMuted ? 'true' : 'false'
);
});
},
async ensureAlertExistence(alert: string, shouldExist: boolean) {
await retry.try(async () => {
const table = await find.byCssSelector(
'.euiBasicTable[data-test-subj="alertsList"]:not(.euiBasicTable-loading)'
);
const $ = await table.parseDomContent();
expect(
$.findTestSubjects('alert-row')
.toArray()
.filter(
(row) =>
$(row)
.findTestSubject('alertsTableCell-alert')
.find('.euiTableCellContent')
.text() === alert
)
).to.eql(shouldExist ? 1 : 0);
});
},
async clickPaginationNextPage() {
const nextButton = await testSubjects.find(`pagination-button-next`);
nextButton.click();
},
async isViewInAppDisabled() {
await retry.try(async () => {
const viewInAppButton = await testSubjects.find(`ruleDetails-viewInApp`);
expect(await viewInAppButton.getAttribute('disabled')).to.eql('true');
});
return true;
},
async isViewInAppEnabled() {
await retry.try(async () => {
const viewInAppButton = await testSubjects.find(`ruleDetails-viewInApp`);
await new Promise((resolve) => {});
expect(await viewInAppButton.getAttribute('disabled')).to.not.eql('true');
});
return true;
},
async clickViewInApp() {
return await testSubjects.click('ruleDetails-viewInApp');
},
async getNoOpAppTitle() {
await retry.try(async () => {
const title = await testSubjects.find('noop-title');
expect(title.isDisplayed()).to.eql(true);
});
return await testSubjects.getVisibleText('noop-title');
},
};
}

View file

@ -13,10 +13,10 @@ export default function ({ loadTestFile }: FtrProviderContext) {
loadTestFile(require.resolve('./empty_page'));
loadTestFile(require.resolve('./navigation'));
loadTestFile(require.resolve('./cases/attachment_framework'));
loadTestFile(require.resolve('./dashboards/build_dashboard'));
loadTestFile(require.resolve('./dashboards/import_dashboard'));
loadTestFile(require.resolve('./advanced_settings'));
loadTestFile(require.resolve('./rules/rule_details'));
loadTestFile(require.resolve('./ml'));
});

View file

@ -0,0 +1,669 @@
/*
* 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 { expect } from 'expect';
import { v4 as uuidv4 } from 'uuid';
import { FtrProviderContext } from '../../../ftr_provider_context';
import {
createEsQueryRule as createRule,
createSlackConnector,
createIndexConnector,
} from '../../../../api_integration/test_suites/common/alerting/helpers/alerting_api_helper';
export enum RuleNotifyWhen {
CHANGE = 'onActionGroupChange',
ACTIVE = 'onActiveAlert',
THROTTLE = 'onThrottleInterval',
}
export default ({ getPageObject, getService }: FtrProviderContext) => {
const svlCommonPage = getPageObject('svlCommonPage');
const svlCommonNavigation = getPageObject('svlCommonNavigation');
const svlTriggersActionsUI = getPageObject('svlTriggersActionsUI');
const svlRuleDetailsUI = getPageObject('svlRuleDetailsUI');
const svlSearchNavigation = getService('svlSearchNavigation');
const testSubjects = getService('testSubjects');
const supertest = getService('supertest');
const find = getService('find');
const retry = getService('retry');
const toasts = getService('toasts');
const comboBox = getService('comboBox');
const openFirstRule = async (ruleName: string) => {
await svlTriggersActionsUI.searchRules(ruleName);
await find.clickDisplayedByCssSelector(`[data-test-subj="rulesList"] [title="${ruleName}"]`);
};
const openRulesSection = async () => {
await svlSearchNavigation.navigateToLandingPage();
await svlCommonNavigation.sidenav.clickLink({ text: 'Alerts' });
};
const navigateToConnectors = async () => {
await svlSearchNavigation.navigateToLandingPage();
await svlCommonNavigation.sidenav.openSection('project_settings_project_nav');
await svlCommonNavigation.sidenav.clickLink({ deepLinkId: 'management' });
await testSubjects.click('app-card-triggersActionsConnectors');
};
const deleteConnector = async (connectorName: string) => {
await svlTriggersActionsUI.searchConnectors(connectorName);
await testSubjects.click('deleteConnector');
await testSubjects.existOrFail('deleteIdsConfirmation');
await testSubjects.click('deleteIdsConfirmation > confirmModalConfirmButton');
await testSubjects.missingOrFail('deleteIdsConfirmation');
};
describe('Rule details', () => {
let ruleIdList: string[];
let connectorIdList: string[];
before(async () => {
await svlCommonPage.login();
});
after(async () => {
await svlCommonPage.forceLogout();
});
describe('Header', () => {
const testRunUuid = uuidv4();
const ruleName = `test-rule-${testRunUuid}`;
const RULE_TYPE_ID = '.es-query';
before(async () => {
const rule = await createRule({
supertest,
consumer: 'alerts',
name: ruleName,
ruleTypeId: RULE_TYPE_ID,
params: {
size: 100,
thresholdComparator: '>',
threshold: [-1],
index: ['alert-test-data'],
timeField: 'date',
esQuery: `{\n \"query\":{\n \"match_all\" : {}\n }\n}`,
timeWindowSize: 20,
timeWindowUnit: 's',
},
actions: [],
});
ruleIdList = [rule.id];
await openRulesSection();
await testSubjects.existOrFail('rulesList');
await openFirstRule(rule.name);
});
after(async () => {
await Promise.all(
ruleIdList.map(async (ruleId) => {
await supertest
.delete(`/api/alerting/rule/${ruleId}`)
.set('kbn-xsrf', 'foo')
.set('x-elastic-internal-origin', 'foo');
})
);
});
it('renders the rule details', async () => {
const headingText = await testSubjects.getVisibleText('ruleDetailsTitle');
expect(headingText.includes(`test-rule-${testRunUuid}`)).toBe(true);
const ruleType = await testSubjects.getVisibleText('ruleTypeLabel');
expect(ruleType).toEqual('Elasticsearch query');
const owner = await testSubjects.getVisibleText('apiKeyOwnerLabel');
expect(owner).toEqual('elastic_serverless');
});
it('should disable the rule', async () => {
const actionsDropdown = await testSubjects.find('statusDropdown');
expect(await actionsDropdown.getVisibleText()).toEqual('Enabled');
await actionsDropdown.click();
const actionsMenuElem = await testSubjects.find('ruleStatusMenu');
const actionsMenuItemElem = await actionsMenuElem.findAllByClassName('euiContextMenuItem');
await actionsMenuItemElem.at(1)?.click();
await retry.try(async () => {
expect(await actionsDropdown.getVisibleText()).toEqual('Disabled');
});
});
it('should allow you to snooze a disabled rule', async () => {
const actionsDropdown = await testSubjects.find('statusDropdown');
expect(await actionsDropdown.getVisibleText()).toEqual('Disabled');
let snoozeBadge = await testSubjects.find('rulesListNotifyBadge-unsnoozed');
await snoozeBadge.click();
const snoozeIndefinite = await testSubjects.find('ruleSnoozeIndefiniteApply');
await snoozeIndefinite.click();
await retry.try(async () => {
await testSubjects.existOrFail('rulesListNotifyBadge-snoozedIndefinitely');
});
// Unsnooze the rule for the next test
snoozeBadge = await testSubjects.find('rulesListNotifyBadge-snoozedIndefinitely');
await snoozeBadge.click();
const snoozeCancel = await testSubjects.find('ruleSnoozeCancel');
await snoozeCancel.click();
});
it('should reenable a disabled the rule', async () => {
const actionsDropdown = await testSubjects.find('statusDropdown');
expect(await actionsDropdown.getVisibleText()).toEqual('Disabled');
await actionsDropdown.click();
const actionsMenuElem = await testSubjects.find('ruleStatusMenu');
const actionsMenuItemElem = await actionsMenuElem.findAllByClassName('euiContextMenuItem');
await actionsMenuItemElem.at(0)?.click();
await retry.try(async () => {
expect(await actionsDropdown.getVisibleText()).toEqual('Enabled');
});
});
it('should snooze the rule', async () => {
let snoozeBadge = await testSubjects.find('rulesListNotifyBadge-unsnoozed');
await snoozeBadge.click();
const snoozeIndefinite = await testSubjects.find('ruleSnoozeIndefiniteApply');
await snoozeIndefinite.click();
await retry.try(async () => {
await testSubjects.existOrFail('rulesListNotifyBadge-snoozedIndefinitely');
});
// Unsnooze the rule for the next test
snoozeBadge = await testSubjects.find('rulesListNotifyBadge-snoozedIndefinitely');
await snoozeBadge.click();
const snoozeCancel = await testSubjects.find('ruleSnoozeCancel');
await snoozeCancel.click();
});
it('should snooze the rule for a set duration', async () => {
let snoozeBadge = await testSubjects.find('rulesListNotifyBadge-unsnoozed');
await snoozeBadge.click();
const snooze8h = await testSubjects.find('linkSnooze8h');
await snooze8h.click();
await retry.try(async () => {
await testSubjects.existOrFail('rulesListNotifyBadge-snoozed');
});
// Unsnooze the rule for the next test
snoozeBadge = await testSubjects.find('rulesListNotifyBadge-snoozed');
await snoozeBadge.click();
const snoozeCancel = await testSubjects.find('ruleSnoozeCancel');
await snoozeCancel.click();
});
it('should add snooze schedule', async () => {
let snoozeBadge = await testSubjects.find('rulesListNotifyBadge-unsnoozed');
await snoozeBadge.click();
const addScheduleButton = await testSubjects.find('ruleAddSchedule');
await addScheduleButton.click();
const saveScheduleButton = await testSubjects.find('scheduler-saveSchedule');
await saveScheduleButton.click();
await retry.try(async () => {
await testSubjects.existOrFail('rulesListNotifyBadge-scheduled');
});
// Unsnooze the rule for the next test
snoozeBadge = await testSubjects.find('rulesListNotifyBadge-scheduled');
await snoozeBadge.click();
const snoozeCancel = await testSubjects.find('ruleRemoveAllSchedules');
await snoozeCancel.click();
const confirmButton = await testSubjects.find('confirmModalConfirmButton');
await confirmButton.click();
});
});
describe('Edit rule button', () => {
const testRunUuid = uuidv4();
const ruleName = `${testRunUuid}`;
const updatedRuleName = `Changed Rule Name ${ruleName}`;
const RULE_TYPE_ID = '.es-query';
before(async () => {
const rule = await createRule({
supertest,
consumer: 'alerts',
name: ruleName,
ruleTypeId: RULE_TYPE_ID,
params: {
size: 100,
thresholdComparator: '>',
threshold: [-1],
index: ['alert-test-data'],
timeField: 'date',
esQuery: `{\n \"query\":{\n \"match_all\" : {}\n }\n}`,
timeWindowSize: 20,
timeWindowUnit: 's',
},
actions: [],
});
ruleIdList = [rule.id];
await openRulesSection();
await testSubjects.existOrFail('rulesList');
await openFirstRule(rule.name);
});
after(async () => {
await Promise.all(
ruleIdList.map(async (ruleId) => {
await supertest
.delete(`/api/alerting/rule/${ruleId}`)
.set('kbn-xsrf', 'foo')
.set('x-elastic-internal-origin', 'foo');
})
);
});
it('should open edit rule flyout', async () => {
const editButton = await testSubjects.find('openEditRuleFlyoutButton');
await editButton.click();
expect(await testSubjects.exists('hasActionsDisabled')).toBe(false);
await testSubjects.setValue('ruleNameInput', updatedRuleName, {
clearWithKeyboard: true,
});
await find.clickByCssSelector('[data-test-subj="saveEditedRuleButton"]:not(disabled)');
await retry.try(async () => {
const resultToast = await toasts.getToastElement(1);
const toastText = await resultToast.getVisibleText();
expect(toastText).toEqual(`Updated '${updatedRuleName}'`);
});
await retry.tryForTime(30 * 1000, async () => {
const headingText = await testSubjects.getVisibleText('ruleDetailsTitle');
expect(headingText.includes(updatedRuleName)).toBe(true);
});
});
it('should reset rule when canceling an edit', async () => {
const editButton = await testSubjects.find('openEditRuleFlyoutButton');
await editButton.click();
await testSubjects.setValue('ruleNameInput', uuidv4(), {
clearWithKeyboard: true,
});
await testSubjects.click('cancelSaveEditedRuleButton');
await testSubjects.existOrFail('confirmRuleCloseModal');
await testSubjects.click('confirmRuleCloseModal > confirmModalConfirmButton');
await find.waitForDeletedByCssSelector('[data-test-subj="cancelSaveEditedRuleButton"]');
await editButton.click();
const nameInputAfterCancel = await testSubjects.find('ruleNameInput');
const textAfterCancel = await nameInputAfterCancel.getAttribute('value');
expect(textAfterCancel).toEqual(updatedRuleName);
});
});
describe('Edit rule with deleted connector', () => {
const ALERT_ACTION_INDEX = 'alert-action-es-query';
const RULE_TYPE_ID = '.es-query';
afterEach(async () => {
await Promise.all(
ruleIdList.map(async (ruleId) => {
await supertest
.delete(`/api/alerting/rule/${ruleId}`)
.set('kbn-xsrf', 'foo')
.set('x-elastic-internal-origin', 'foo');
})
);
await Promise.all(
connectorIdList.map(async (connectorId) => {
await supertest
.delete(`/api/actions/connector/${connectorId}`)
.set('kbn-xsrf', 'foo')
.set('x-elastic-internal-origin', 'foo');
})
);
});
it('should show and update deleted connectors when there are existing connectors of the same type', async () => {
const testRunUuid = uuidv4();
const connector1 = await createSlackConnector({
supertest,
name: `slack-${testRunUuid}-${0}`,
});
const connector2 = await createSlackConnector({
supertest,
name: `slack-${testRunUuid}-${1}`,
});
connectorIdList = [connector2.id];
const rule = await createRule({
supertest,
consumer: 'alerts',
name: testRunUuid,
ruleTypeId: RULE_TYPE_ID,
schedule: { interval: '1m' },
params: {
size: 100,
thresholdComparator: '>',
threshold: [-1],
index: ['alert-test-data'],
timeField: 'date',
esQuery: `{\n \"query\":{\n \"match_all\" : {}\n }\n}`,
timeWindowSize: 20,
timeWindowUnit: 's',
},
actions: [
{
group: 'query matched',
id: connector1.id,
params: { level: 'info', message: ' {{context.message}}' },
frequency: {
summary: false,
notify_when: RuleNotifyWhen.THROTTLE,
throttle: '1m',
},
},
],
});
ruleIdList = [rule.id];
await openRulesSection();
await testSubjects.existOrFail('rulesList');
await navigateToConnectors();
await deleteConnector(connector1.name);
await retry.try(async () => {
const resultToast = await toasts.getToastElement(1);
const toastText = await resultToast.getVisibleText();
expect(toastText).toEqual('Deleted 1 connector');
});
await openRulesSection();
await openFirstRule(rule.name);
const editButton = await testSubjects.find('openEditRuleFlyoutButton');
await editButton.click();
expect(await testSubjects.exists('hasActionsDisabled')).toEqual(false);
expect(await testSubjects.exists('addNewActionConnectorActionGroup-0')).toEqual(false);
expect(await testSubjects.exists('alertActionAccordion-0')).toEqual(true);
expect(await testSubjects.exists('selectActionConnector-.slack-0')).toEqual(true);
// click the super selector the reveal the options
await testSubjects.click('selectActionConnector-.slack-0');
await testSubjects.click(`dropdown-connector-${connector2.id}`);
expect(await testSubjects.exists('addNewActionConnectorActionGroup-0')).toEqual(true);
});
it('should show and update deleted connectors when there are no existing connectors of the same type', async () => {
const testRunUuid = uuidv4();
const connector = await createIndexConnector({
supertest,
name: `index-${testRunUuid}-${2}`,
indexName: ALERT_ACTION_INDEX,
});
const rule = await createRule({
supertest,
consumer: 'alerts',
name: testRunUuid,
ruleTypeId: RULE_TYPE_ID,
schedule: { interval: '1m' },
params: {
size: 100,
thresholdComparator: '>',
threshold: [-1],
index: ['alert-test-data'],
timeField: 'date',
esQuery: `{\n \"query\":{\n \"match_all\" : {}\n }\n}`,
timeWindowSize: 20,
timeWindowUnit: 's',
},
actions: [
{
group: 'query matched',
id: connector.id,
params: { level: 'info', message: ' {{context.message}}' },
frequency: {
summary: false,
notify_when: RuleNotifyWhen.THROTTLE,
throttle: '1m',
},
},
{
group: 'recovered',
id: connector.id,
params: { level: 'info', message: ' {{context.message}}' },
frequency: {
summary: false,
notify_when: RuleNotifyWhen.THROTTLE,
throttle: '1m',
},
},
],
});
ruleIdList = [rule.id];
await openRulesSection();
await testSubjects.existOrFail('rulesList');
await navigateToConnectors();
await deleteConnector(connector.name);
await retry.try(async () => {
const resultToast = await toasts.getToastElement(1);
const toastText = await resultToast.getVisibleText();
expect(toastText).toEqual('Deleted 1 connector');
});
await openRulesSection();
await openFirstRule(rule.name);
const editButton = await testSubjects.find('openEditRuleFlyoutButton');
await editButton.click();
expect(await testSubjects.exists('hasActionsDisabled')).toEqual(false);
expect(await testSubjects.exists('addNewActionConnectorActionGroup-0')).toEqual(false);
expect(await testSubjects.exists('alertActionAccordion-0')).toEqual(true);
expect(await testSubjects.exists('addNewActionConnectorActionGroup-1')).toEqual(false);
expect(await testSubjects.exists('alertActionAccordion-1')).toEqual(true);
await testSubjects.click('createActionConnectorButton-0');
await testSubjects.existOrFail('connectorAddModal');
await testSubjects.setValue('nameInput', 'new connector');
await retry.try(async () => {
// At times we find the driver controlling the ComboBox in tests
// can select the wrong item, this ensures we always select the correct index
await comboBox.set('connectorIndexesComboBox', 'test-index');
expect(
await comboBox.isOptionSelected(
await testSubjects.find('connectorIndexesComboBox'),
'test-index'
)
).toEqual(true);
});
await testSubjects.click('connectorAddModal > saveActionButtonModal');
await testSubjects.missingOrFail('deleteIdsConfirmation');
expect(await testSubjects.exists('addNewActionConnectorActionGroup-0')).toEqual(true);
expect(await testSubjects.exists('addNewActionConnectorActionGroup-1')).toEqual(true);
await openRulesSection();
await testSubjects.existOrFail('rulesList');
await navigateToConnectors();
await deleteConnector('new connector');
});
});
describe('Edit rule with legacy rule-level notify values', () => {
afterEach(async () => {
await Promise.all(
ruleIdList.map(async (ruleId) => {
await supertest
.delete(`/api/alerting/rule/${ruleId}`)
.set('kbn-xsrf', 'foo')
.set('x-elastic-internal-origin', 'foo');
})
);
await Promise.all(
connectorIdList.map(async (connectorId) => {
await supertest
.delete(`/api/actions/connector/${connectorId}`)
.set('kbn-xsrf', 'foo')
.set('x-elastic-internal-origin', 'foo');
})
);
});
it('should convert rule-level params to action-level params and save the alert successfully', async () => {
const testRunUuid = uuidv4();
const RULE_TYPE_ID = '.es-query';
const connector1 = await createSlackConnector({
supertest,
name: `slack-${testRunUuid}-${0}`,
});
const connector2 = await createSlackConnector({
supertest,
name: `slack-${testRunUuid}-${1}`,
});
connectorIdList = [connector1.id, connector2.id];
const rule = await createRule({
supertest,
consumer: 'alerts',
name: `test-rule-${testRunUuid}`,
ruleTypeId: RULE_TYPE_ID,
schedule: { interval: '1m' },
params: {
size: 100,
thresholdComparator: '>',
threshold: [-1],
index: ['alert-test-data'],
timeField: 'date',
esQuery: `{\n \"query\":{\n \"match_all\" : {}\n }\n}`,
timeWindowSize: 20,
timeWindowUnit: 's',
},
actions: [connector1, connector2].map((connector) => ({
id: connector.id,
group: 'query matched',
params: {
message: 'from alert 1s',
level: 'warn',
},
frequency: {
summary: false,
notify_when: RuleNotifyWhen.THROTTLE,
throttle: '2d',
},
})),
});
ruleIdList = [rule.id];
const updatedRuleName = `Changed rule ${rule.name}`;
await openRulesSection();
await testSubjects.existOrFail('rulesList');
await openFirstRule(rule.name);
const editButton = await testSubjects.find('openEditRuleFlyoutButton');
await editButton.click();
const notifyWhenSelect = await testSubjects.find('notifyWhenSelect');
expect(await notifyWhenSelect.getVisibleText()).toEqual('On custom action intervals');
const throttleInput = await testSubjects.find('throttleInput');
const throttleUnitInput = await testSubjects.find('throttleUnitInput');
expect(await throttleInput.getAttribute('value')).toEqual('2');
expect(await throttleUnitInput.getAttribute('value')).toEqual('d');
await testSubjects.setValue('ruleNameInput', updatedRuleName, {
clearWithKeyboard: true,
});
await find.clickByCssSelector('[data-test-subj="saveEditedRuleButton"]:not(disabled)');
await retry.try(async () => {
const resultToast = await toasts.getToastElement(1);
const toastText = await resultToast.getVisibleText();
expect(toastText).toEqual(`Updated '${updatedRuleName}'`);
});
});
});
describe('View In App', () => {
const ruleName = uuidv4();
const RULE_TYPE_ID = '.es-query';
afterEach(async () => {
await Promise.all(
ruleIdList.map(async (ruleId) => {
await supertest
.delete(`/api/alerting/rule/${ruleId}`)
.set('kbn-xsrf', 'foo')
.set('x-elastic-internal-origin', 'foo');
})
);
});
it('renders a disabled rule details view in app button', async () => {
const rule = await createRule({
supertest,
consumer: 'alerts',
name: ruleName,
ruleTypeId: RULE_TYPE_ID,
params: {
size: 100,
thresholdComparator: '>',
threshold: [-1],
index: ['alert-test-data'],
timeField: 'date',
esQuery: `{\n \"query\":{\n \"match_all\" : {}\n }\n}`,
timeWindowSize: 20,
timeWindowUnit: 's',
},
actions: [],
});
ruleIdList = [rule.id];
await openRulesSection();
await testSubjects.existOrFail('rulesList');
await openFirstRule(rule.name);
expect(await svlRuleDetailsUI.isViewInAppDisabled()).toEqual(true);
});
});
});
};