Skip to content

Commit

Permalink
Extend alerts table tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Kerry350 committed Sep 6, 2021
1 parent 82426e9 commit 30a197a
Show file tree
Hide file tree
Showing 5 changed files with 229 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,9 @@ export function AlertsFlyout({
];

return (
<EuiFlyout onClose={onClose} size="s">
<EuiFlyout onClose={onClose} size="s" data-test-subj="alertsFlyout">
<EuiFlyoutHeader>
<EuiTitle size="m">
<EuiTitle size="m" data-test-subj="alertsFlyoutTitle">
<h2>{alertData.fields[ALERT_RULE_NAME]}</h2>
</EuiTitle>
<EuiSpacer size="s" />
Expand All @@ -141,13 +141,23 @@ export function AlertsFlyout({
compressed={true}
type="responsiveColumn"
listItems={overviewListItems}
titleProps={{
'data-test-subj': 'alertsFlyoutDescriptionListTitle',
}}
descriptionProps={{
'data-test-subj': 'alertsFlyoutDescriptionListDescription',
}}
/>
</EuiFlyoutBody>
{alertData.link && !isInApp && (
<EuiFlyoutFooter>
<EuiFlexGroup justifyContent="flexEnd">
<EuiFlexItem grow={false}>
<EuiButton href={prepend && prepend(alertData.link)} fill>
<EuiButton
href={prepend && prepend(alertData.link)}
data-test-subj="alertsFlyoutViewInAppButton"
fill
>
View in app
</EuiButton>
</EuiFlexItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ function ObservabilityActions({
iconType="expand"
color="text"
onClick={() => setFlyoutAlert(alert)}
data-test-subj="toggleFlyoutButton"
/>
</EuiFlexItem>
<EuiFlexItem>
Expand Down
117 changes: 91 additions & 26 deletions x-pack/test/functional/apps/observability/alerts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,13 @@
*/

import expect from '@kbn/expect';
import querystring from 'querystring';
import { FtrProviderContext } from '../../../ftr_provider_context';

// Based on the x-pack/test/functional/es_archives/observability/alerts archive.
const DATE_WITH_DATA = {
rangeFrom: '2021-09-01T13:36:22.109Z',
rangeTo: '2021-09-03T13:36:22.109Z',
};
async function asyncForEach(array, callback) {
for (let index = 0; index < array.length; index++) {
await callback(array[index], index, array);
}
}

export default ({ getPageObjects, getService }: FtrProviderContext) => {
const esArchiver = getService('esArchiver');
Expand All @@ -23,14 +22,11 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {

const pageObjects = getPageObjects(['common']);
const testSubjects = getService('testSubjects');
const Observability = getService('observability');

before(async () => {
await esArchiver.load('x-pack/test/functional/es_archives/observability/alerts');
await pageObjects.common.navigateToUrlWithBrowserHistory(
'observability',
'/alerts',
`?${querystring.stringify(DATE_WITH_DATA)}`
);
await Observability.alerts.navigateToTimeWithData();
});

after(async () => {
Expand All @@ -39,51 +35,120 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {

describe('Alerts table', () => {
it('Renders the table', async () => {
await testSubjects.existOrFail('events-viewer-panel');
await Observability.alerts.getTableOrFail();
});

it('Renders the correct number of cells', async () => {
// NOTE: This isn't ideal, but EuiDataGrid doesn't really have the concept of "rows"
const cells = await testSubjects.findAll('dataGridRowCell');
const cells = await Observability.alerts.getTableCells();
expect(cells.length).to.be(72);
});

describe('Filtering', () => {
afterEach(async () => {
await Observability.alerts.clearQueryBar();
});

after(async () => {
// NOTE: We do this as the query bar takes the place of the datepicker when it is in focus, so we'll reset
// back to default.
await Observability.alerts.submitQuery('');
});

it('Autocompletion works', async () => {
const queryBar = await testSubjects.find('queryInput');
await queryBar.clearValueWithKeyboard({ charByChar: true });
await queryBar.type('kibana.alert.s');
await Observability.alerts.typeInQueryBar('kibana.alert.s');
await testSubjects.existOrFail('autocompleteSuggestion-field-kibana.alert.start-');
await testSubjects.existOrFail('autocompleteSuggestion-field-kibana.alert.status-');
});

it('Applies filters correctly', async () => {
const queryBar = await testSubjects.find('queryInput');
await queryBar.clearValueWithKeyboard({ charByChar: true });
await queryBar.type('kibana.alert.status: recovered');
await (await testSubjects.find('querySubmitButton')).click();
const cells = await testSubjects.findAll('dataGridRowCell');
await Observability.alerts.submitQuery('kibana.alert.status: recovered');
const cells = await Observability.alerts.getTableCells();
expect(cells.length).to.be(24);
});

it('Displays a no data state when filters produce zero results', async () => {
const queryBar = await testSubjects.find('queryInput');
await queryBar.clearValueWithKeyboard({ charByChar: true });
await queryBar.type('kibana.alert.consumer: uptime');
await (await testSubjects.find('querySubmitButton')).click();
await Observability.alerts.submitQuery('kibana.alert.consumer: uptime');
await testSubjects.existOrFail('events-container-loading-false');
});
});

describe('Date selection', () => {
after(async () => {
await Observability.alerts.navigateToTimeWithData();
});

it('Correctly applies date picker selections', async () => {
await (await testSubjects.find('superDatePickerToggleQuickMenuButton')).click();
// We shouldn't expect any data for the last 15 minutes
await (await testSubjects.find('superDatePickerCommonlyUsed_Last_15 minutes')).click();
await testSubjects.existOrFail('events-container-loading-false');
await Observability.alerts.getNoDataStateOrFail();
await pageObjects.common.waitUntilUrlIncludes('rangeFrom=now-15m&rangeTo=now');
});
});

describe('Flyout', () => {
it('Can be opened', async () => {
await Observability.alerts.toggleFlyout();
await Observability.alerts.getAlertsFlyoutOrFail();
});

it('Can be closed', async () => {
await Observability.alerts.closeAlertsFlyout();
await testSubjects.missingOrFail('alertsFlyout');
});

describe('When open', async () => {
before(async () => {
await Observability.alerts.toggleFlyout();
});

after(async () => {
await Observability.alerts.closeAlertsFlyout();
});

it('Displays the correct title', async () => {
const titleText = await (
await Observability.alerts.getAlertsFlyoutTitle()
).getVisibleText();
expect(titleText).to.contain('Log threshold');
});

it('Displays the correct content', async () => {
const flyoutTitles = await Observability.alerts.getAlertsFlyoutDescriptionListTitles();
const flyoutDescriptions = await Observability.alerts.getAlertsFlyoutDescriptionListDescriptions();

const expectedTitles = [
'Status',
'Last updated',
'Duration',
'Expected value',
'Actual value',
'Rule type',
];
const expectedDescriptions = [
'Active',
'Sep 2, 2021 @ 12:54:09.674',
'15 minutes',
'100.25',
'1957',
'Log threshold',
];

await asyncForEach(flyoutTitles, async (title, index) => {
expect(await title.getVisibleText()).to.be(expectedTitles[index]);
});

await asyncForEach(flyoutDescriptions, async (description, index) => {
expect(await description.getVisibleText()).to.be(expectedDescriptions[index]);
});
});

it('Displays a View in App button', async () => {
await Observability.alerts.getAlertsFlyoutViewInAppButtonOrFail();
});
});
});
});
});
};
121 changes: 121 additions & 0 deletions x-pack/test/functional/services/observability/alerts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/*
* 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 querystring from 'querystring';
import { FtrProviderContext } from '../../ftr_provider_context';

// Based on the x-pack/test/functional/es_archives/observability/alerts archive.
const DATE_WITH_DATA = {
rangeFrom: '2021-09-01T13:36:22.109Z',
rangeTo: '2021-09-03T13:36:22.109Z',
};

export function ObservabilityAlertsProvider({ getPageObjects, getService }: FtrProviderContext) {
const testSubjects = getService('testSubjects');
const pageObjects = getPageObjects(['common']);

const navigateToTimeWithData = async () => {
return await pageObjects.common.navigateToUrlWithBrowserHistory(
'observability',
'/alerts',
`?${querystring.stringify(DATE_WITH_DATA)}`
);
};

const getTableCells = async () => {
// NOTE: This isn't ideal, but EuiDataGrid doesn't really have the concept of "rows"
return await testSubjects.findAll('dataGridRowCell');
};

const getTableOrFail = async () => {
return await testSubjects.existOrFail('events-viewer-panel');
};

const getNoDataStateOrFail = async () => {
return await testSubjects.existOrFail('events-container-loading-false');
};

// Query Bar
const getQueryBar = async () => {
return await testSubjects.find('queryInput');
};

const getQuerySubmitButton = async () => {
return await testSubjects.find('querySubmitButton');
};

const clearQueryBar = async () => {
return await (await getQueryBar()).clearValueWithKeyboard({ charByChar: true });
};

const typeInQueryBar = async (query: string) => {
return await (await getQueryBar()).type(query);
};

const submitQuery = async (query: string) => {
await typeInQueryBar(query);
return await (await getQuerySubmitButton()).click();
};

// Flyout
const getToggleFlyoutButton = async () => {
return await testSubjects.find('toggleFlyoutButton');
};

const toggleFlyout = async () => {
return await (await getToggleFlyoutButton()).click();
};

const getAlertsFlyout = async () => {
return await testSubjects.find('alertsFlyout');
};

const getAlertsFlyoutOrFail = async () => {
return await testSubjects.existOrFail('alertsFlyout');
};

const getAlertsFlyoutTitle = async () => {
return await testSubjects.find('alertsFlyoutTitle');
};

const closeAlertsFlyout = async () => {
const flyout = await getAlertsFlyout();
return await (await testSubjects.findDescendant('euiFlyoutCloseButton', flyout)).click();
};

const getAlertsFlyoutViewInAppButtonOrFail = async () => {
return await testSubjects.existOrFail('alertsFlyoutViewInAppButton');
};

const getAlertsFlyoutDescriptionListTitles = async () => {
const flyout = await getAlertsFlyout();
return await testSubjects.findAllDescendant('alertsFlyoutDescriptionListTitle', flyout);
};

const getAlertsFlyoutDescriptionListDescriptions = async () => {
const flyout = await getAlertsFlyout();
return await testSubjects.findAllDescendant('alertsFlyoutDescriptionListDescription', flyout);
};

return {
clearQueryBar,
typeInQueryBar,
submitQuery,
getTableCells,
getTableOrFail,
getNoDataStateOrFail,
toggleFlyout,
getAlertsFlyout,
getAlertsFlyoutTitle,
closeAlertsFlyout,
navigateToTimeWithData,
getAlertsFlyoutOrFail,
getAlertsFlyoutViewInAppButtonOrFail,
getAlertsFlyoutDescriptionListTitles,
getAlertsFlyoutDescriptionListDescriptions,
};
}
3 changes: 3 additions & 0 deletions x-pack/test/functional/services/observability/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@

import { FtrProviderContext } from '../../ftr_provider_context';
import { ObservabilityUsersProvider } from './users';
import { ObservabilityAlertsProvider } from './alerts';

export function ObservabilityProvider(context: FtrProviderContext) {
const users = ObservabilityUsersProvider(context);
const alerts = ObservabilityAlertsProvider(context);

return {
users,
alerts,
};
}

0 comments on commit 30a197a

Please sign in to comment.