[Uptime] Fix uptime alerting fly outs within alerting app (#123031)

This commit is contained in:
Shahzad 2022-01-14 18:24:03 +01:00 committed by GitHub
parent 2b1e1f3c59
commit cf96e546a7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 158 additions and 27 deletions

View file

@ -0,0 +1,9 @@
/*
* 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.
*/
export * from './tls_alert_flyouts_in_alerting_app';
export * from './status_alert_flyouts_in_alerting_app';

View file

@ -0,0 +1,68 @@
/*
* 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 { journey, step, expect, before } from '@elastic/synthetics';
import { assertText, byTestId, loginToKibana, waitForLoadingToFinish } from '../utils';
journey('StatusFlyoutInAlertingApp', async ({ page, params }) => {
before(async () => {
await waitForLoadingToFinish({ page });
});
const baseUrl = `${params.kibanaUrl}/app/management/insightsAndAlerting/triggersActions/rules`;
step('Go to Alerting app', async () => {
await page.goto(`${baseUrl}`, {
waitUntil: 'networkidle',
});
await loginToKibana({ page });
});
step('Open monitor status flyout', async () => {
await page.click(byTestId('createFirstAlertButton'));
await waitForLoadingToFinish({ page });
await page.click(byTestId('"xpack.uptime.alerts.monitorStatus-SelectOption"'));
await waitForLoadingToFinish({ page });
await assertText({ page, text: 'This alert will apply to approximately 0 monitors.' });
});
step('can add filters', async () => {
await page.click('text=Add filter');
await page.click(byTestId('"uptimeAlertAddFilter.monitor.type"'));
await page.click(byTestId('"uptimeCreateStatusAlert.filter_scheme"'));
});
step('can open query bar', async () => {
await page.click(byTestId('"xpack.uptime.alerts.monitorStatus.filterBar"'));
await page.fill(byTestId('"xpack.uptime.alerts.monitorStatus.filterBar"'), 'monitor.type : ');
await waitForLoadingToFinish({ page });
await assertText({ page, text: 'browser' });
await assertText({ page, text: 'http' });
const suggestionItem = await page.$(byTestId('autoCompleteSuggestionText'));
expect(await suggestionItem?.textContent()).toBe('"browser" ');
await page.click(byTestId('euiFlyoutCloseButton'));
await page.click(byTestId('confirmModalConfirmButton'));
});
step('Open tls alert flyout', async () => {
await page.click(byTestId('createFirstAlertButton'));
await waitForLoadingToFinish({ page });
await page.click(byTestId('"xpack.uptime.alerts.tlsCertificate-SelectOption"'));
await waitForLoadingToFinish({ page });
await assertText({ page, text: 'has a certificate expiring within' });
});
step('Tls alert flyout has setting values', async () => {
await assertText({ page, text: '30 days' });
await assertText({ page, text: '730 days' });
});
});

View file

@ -0,0 +1,37 @@
/*
* 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 { journey, step, before } from '@elastic/synthetics';
import { assertText, byTestId, loginToKibana, waitForLoadingToFinish } from '../utils';
journey('TlsFlyoutInAlertingApp', async ({ page, params }) => {
before(async () => {
await waitForLoadingToFinish({ page });
});
const baseUrl = `${params.kibanaUrl}/app/management/insightsAndAlerting/triggersActions/rules`;
step('Go to Alerting app', async () => {
await page.goto(`${baseUrl}`, {
waitUntil: 'networkidle',
});
await loginToKibana({ page });
});
step('Open tls alert flyout', async () => {
await page.click(byTestId('createFirstAlertButton'));
await waitForLoadingToFinish({ page });
await page.click(byTestId('"xpack.uptime.alerts.tlsCertificate-SelectOption"'));
await waitForLoadingToFinish({ page });
await assertText({ page, text: 'has a certificate expiring within' });
});
step('Tls alert flyout has setting values', async () => {
await assertText({ page, text: '30 days' });
await assertText({ page, text: '730 days' });
});
});

View file

@ -7,3 +7,4 @@
export * from './uptime.journey';
export * from './step_duration.journey';
export * from './alerts';

View file

@ -5,8 +5,7 @@
* 2.0.
*/
import { Page } from '@elastic/synthetics';
import { byTestId } from './uptime.journey';
import { expect, Page } from '@elastic/synthetics';
export async function waitForLoadingToFinish({ page }: { page: Page }) {
while (true) {
@ -25,3 +24,12 @@ export async function loginToKibana({ page }: { page: Page }) {
await waitForLoadingToFinish({ page });
}
export const byTestId = (testId: string) => {
return `[data-test-subj=${testId}]`;
};
export const assertText = async ({ page, text }: { page: Page; text: string }) => {
await page.waitForSelector(`text=${text}`);
expect(await page.$(`text=${text}`)).toBeTruthy();
};

View file

@ -13,18 +13,22 @@ import { esArchiverLoad, esArchiverUnload } from './tasks/es_archiver';
import './journeys';
const listOfJourneys = [
'uptime',
'StepsDuration',
'TlsFlyoutInAlertingApp',
'StatusFlyoutInAlertingApp',
] as const;
export function playwrightRunTests({ headless, match }: { headless: boolean; match?: string }) {
return async ({ getService }: any) => {
const result = await playwrightStart(getService, headless, match);
if (
result?.uptime &&
result.uptime.status !== 'succeeded' &&
result.StepsDuration &&
result.StepsDuration.status !== 'succeeded'
) {
throw new Error('Tests failed');
}
listOfJourneys.forEach((journey) => {
if (result?.[journey] && result[journey].status !== 'succeeded') {
throw new Error('Tests failed');
}
});
};
}

View file

@ -6,10 +6,11 @@
*/
import { useDispatch, useSelector } from 'react-redux';
import React, { useCallback } from 'react';
import React, { useCallback, useEffect } from 'react';
import { AlertTlsComponent } from '../alert_tls';
import { setAlertFlyoutVisible } from '../../../../state/actions';
import { selectDynamicSettings } from '../../../../state/selectors';
import { getDynamicSettings } from '../../../../state/actions/dynamic_settings';
export const AlertTls: React.FC<{}> = () => {
const dispatch = useDispatch();
@ -18,6 +19,13 @@ export const AlertTls: React.FC<{}> = () => {
[dispatch]
);
const { settings } = useSelector(selectDynamicSettings);
useEffect(() => {
if (typeof settings === 'undefined') {
dispatch(getDynamicSettings());
}
}, [dispatch, settings]);
return (
<AlertTlsComponent
ageThreshold={settings?.certAgeThreshold}

View file

@ -24,6 +24,7 @@ describe('AddFilterButton component', () => {
disabled={false}
flush="left"
iconType="plusInCircleFilled"
isLoading={false}
onClick={[Function]}
size="s"
>
@ -90,6 +91,7 @@ describe('AddFilterButton component', () => {
disabled={false}
flush="left"
iconType="plusInCircleFilled"
isLoading={false}
onClick={[Function]}
size="s"
>
@ -143,6 +145,7 @@ describe('AddFilterButton component', () => {
disabled={true}
flush="left"
iconType="plusInCircleFilled"
isLoading={false}
onClick={[Function]}
size="s"
>

View file

@ -8,6 +8,7 @@
import React, { useState } from 'react';
import { EuiButtonEmpty, EuiContextMenuItem, EuiContextMenuPanel, EuiPopover } from '@elastic/eui';
import * as labels from '../translations';
import { useIndexPattern } from '../../../../contexts/uptime_index_pattern_context';
interface Props {
newFilters: string[];
@ -20,6 +21,8 @@ export const AddFilterButton: React.FC<Props> = ({ newFilters, onNewFilter, aler
const getSelectedItems = (fieldName: string) => alertFilters?.[fieldName] ?? [];
const indexPattern = useIndexPattern();
const onButtonClick = () => {
setPopover(!isPopoverOpen);
};
@ -62,6 +65,7 @@ export const AddFilterButton: React.FC<Props> = ({ newFilters, onNewFilter, aler
onClick={onButtonClick}
size="s"
flush="left"
isLoading={!indexPattern}
>
{labels.ADD_FILTER}
</EuiButtonEmpty>

View file

@ -5,12 +5,10 @@
* 2.0.
*/
import React, { createContext, useContext, useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import React, { createContext, useContext } from 'react';
import { useFetcher } from '../../../observability/public';
import { DataPublicPluginStart, IndexPattern } from '../../../../../src/plugins/data/public';
import { indexStatusSelector, selectDynamicSettings } from '../state/selectors';
import { getDynamicSettings } from '../state/actions/dynamic_settings';
import { useHasData } from '../components/overview/empty_state/use_has_data';
export const UptimeIndexPatternContext = createContext({} as IndexPattern);
@ -18,16 +16,7 @@ export const UptimeIndexPatternContextProvider: React.FC<{ data: DataPublicPlugi
children,
data: { indexPatterns },
}) => {
const { settings } = useSelector(selectDynamicSettings);
const { data: indexStatus } = useSelector(indexStatusSelector);
const dispatch = useDispatch();
useEffect(() => {
if (typeof settings === 'undefined') {
dispatch(getDynamicSettings());
}
}, [dispatch, settings]);
const { settings, data: indexStatus } = useHasData();
const heartbeatIndices = settings?.heartbeatIndices || '';

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { takeLatest, put, call } from 'redux-saga/effects';
import { takeLeading, put, call, takeLatest } from 'redux-saga/effects';
import { Action } from 'redux-actions';
import { i18n } from '@kbn/i18n';
import { fetchEffectFactory } from './fetch_effect';
@ -25,7 +25,7 @@ import { DynamicSettings } from '../../../common/runtime_types';
import { kibanaService } from '../kibana_service';
export function* fetchDynamicSettingsEffect() {
yield takeLatest(
yield takeLeading(
String(getDynamicSettings),
fetchEffectFactory(getDynamicSettingsAPI, getDynamicSettingsSuccess, getDynamicSettingsFail)
);