mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[Uptime] Fix uptime alerting fly outs within alerting app (#123031)
This commit is contained in:
parent
2b1e1f3c59
commit
cf96e546a7
11 changed files with 158 additions and 27 deletions
9
x-pack/plugins/uptime/e2e/journeys/alerts/index.ts
Normal file
9
x-pack/plugins/uptime/e2e/journeys/alerts/index.ts
Normal 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';
|
|
@ -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' });
|
||||
});
|
||||
});
|
|
@ -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' });
|
||||
});
|
||||
});
|
|
@ -7,3 +7,4 @@
|
|||
|
||||
export * from './uptime.journey';
|
||||
export * from './step_duration.journey';
|
||||
export * from './alerts';
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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"
|
||||
>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 || '';
|
||||
|
||||
|
|
|
@ -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)
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue