diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_details.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_details.test.tsx index 2625768dc72421..64069009f6589c 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_details.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_details.test.tsx @@ -63,7 +63,7 @@ describe('alert_details', () => { ).containsMatchingElement(

- {alert.name} + {alert.name} = ({ -

- {alert.name} +

+ {alert.name} { const alertState = mockAlertState(); const instances: AlertInstanceListItem[] = [ - alertInstanceToListItem(alert, 'first_instance', alertState.alertInstances!.first_instance), - alertInstanceToListItem(alert, 'second_instance', alertState.alertInstances!.second_instance), + alertInstanceToListItem( + fakeNow.getTime(), + alert, + 'first_instance', + alertState.alertInstances!.first_instance + ), + alertInstanceToListItem( + fakeNow.getTime(), + alert, + 'second_instance', + alertState.alertInstances!.second_instance + ), ]; expect( @@ -48,6 +58,24 @@ describe('alert_instances', () => { ).toEqual(instances); }); + it('render a hidden field with duration epoch', () => { + const alert = mockAlert(); + const alertState = mockAlertState(); + + expect( + shallow( + + ) + .find('[name="alertInstancesDurationEpoch"]') + .prop('value') + ).toEqual(fake2MinutesAgo.getTime()); + }); + it('render all active alert instances', () => { const alert = mockAlert(); const instances = { @@ -75,8 +103,8 @@ describe('alert_instances', () => { .find(EuiBasicTable) .prop('items') ).toEqual([ - alertInstanceToListItem(alert, 'us-central', instances['us-central']), - alertInstanceToListItem(alert, 'us-east', instances['us-east']), + alertInstanceToListItem(fakeNow.getTime(), alert, 'us-central', instances['us-central']), + alertInstanceToListItem(fakeNow.getTime(), alert, 'us-east', instances['us-east']), ]); }); @@ -98,8 +126,8 @@ describe('alert_instances', () => { .find(EuiBasicTable) .prop('items') ).toEqual([ - alertInstanceToListItem(alert, 'us-west'), - alertInstanceToListItem(alert, 'us-east'), + alertInstanceToListItem(fakeNow.getTime(), alert, 'us-west'), + alertInstanceToListItem(fakeNow.getTime(), alert, 'us-east'), ]); }); }); @@ -117,7 +145,7 @@ describe('alertInstanceToListItem', () => { }, }; - expect(alertInstanceToListItem(alert, 'id', instance)).toEqual({ + expect(alertInstanceToListItem(fakeNow.getTime(), alert, 'id', instance)).toEqual({ instance: 'id', status: { label: 'Active', healthColor: 'primary' }, start, @@ -140,7 +168,7 @@ describe('alertInstanceToListItem', () => { }, }; - expect(alertInstanceToListItem(alert, 'id', instance)).toEqual({ + expect(alertInstanceToListItem(fakeNow.getTime(), alert, 'id', instance)).toEqual({ instance: 'id', status: { label: 'Active', healthColor: 'primary' }, start, @@ -153,7 +181,7 @@ describe('alertInstanceToListItem', () => { const alert = mockAlert(); const instance: RawAlertInstance = {}; - expect(alertInstanceToListItem(alert, 'id', instance)).toEqual({ + expect(alertInstanceToListItem(fakeNow.getTime(), alert, 'id', instance)).toEqual({ instance: 'id', status: { label: 'Active', healthColor: 'primary' }, start: undefined, @@ -168,7 +196,7 @@ describe('alertInstanceToListItem', () => { meta: {}, }; - expect(alertInstanceToListItem(alert, 'id', instance)).toEqual({ + expect(alertInstanceToListItem(fakeNow.getTime(), alert, 'id', instance)).toEqual({ instance: 'id', status: { label: 'Active', healthColor: 'primary' }, start: undefined, @@ -181,7 +209,7 @@ describe('alertInstanceToListItem', () => { const alert = mockAlert({ mutedInstanceIds: ['id'], }); - expect(alertInstanceToListItem(alert, 'id')).toEqual({ + expect(alertInstanceToListItem(fakeNow.getTime(), alert, 'id')).toEqual({ instance: 'id', status: { label: 'Inactive', healthColor: 'subdued' }, start: undefined, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_instances.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_instances.tsx index 98aa981f40d116..fa4d8f66cd7bf0 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_instances.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_instances.tsx @@ -23,6 +23,7 @@ type AlertInstancesProps = { alert: Alert; alertState: AlertTaskState; requestRefresh: () => Promise; + durationEpoch?: number; } & Pick; export const alertInstancesTableColumns = ( @@ -134,6 +135,7 @@ export function AlertInstances({ muteAlertInstance, unmuteAlertInstance, requestRefresh, + durationEpoch = Date.now(), }: AlertInstancesProps) { const [pagination, setPagination] = useState({ index: 0, @@ -142,10 +144,10 @@ export function AlertInstances({ const mergedAlertInstances = [ ...Object.entries(alertInstances).map(([instanceId, instance]) => - alertInstanceToListItem(alert, instanceId, instance) + alertInstanceToListItem(durationEpoch, alert, instanceId, instance) ), ...difference(alert.mutedInstanceIds, Object.keys(alertInstances)).map(instanceId => - alertInstanceToListItem(alert, instanceId) + alertInstanceToListItem(durationEpoch, alert, instanceId) ), ]; const pageOfAlertInstances = getPage(mergedAlertInstances, pagination); @@ -158,25 +160,33 @@ export function AlertInstances({ }; return ( - { - setPagination(changedPage); - }} - rowProps={() => ({ - 'data-test-subj': 'alert-instance-row', - })} - cellProps={() => ({ - 'data-test-subj': 'cell', - })} - columns={alertInstancesTableColumns(onMuteAction)} - data-test-subj="alertInstancesList" - /> + + + { + setPagination(changedPage); + }} + rowProps={() => ({ + 'data-test-subj': 'alert-instance-row', + })} + cellProps={() => ({ + 'data-test-subj': 'cell', + })} + columns={alertInstancesTableColumns(onMuteAction)} + data-test-subj="alertInstancesList" + /> + ); } export const AlertInstancesWithApi = withBulkAlertOperations(AlertInstances); @@ -207,9 +217,11 @@ const INACTIVE_LABEL = i18n.translate( { defaultMessage: 'Inactive' } ); -const durationSince = (start?: Date) => (start ? Date.now() - start.getTime() : 0); +const durationSince = (durationEpoch: number, startTime?: number) => + startTime ? durationEpoch - startTime : 0; export function alertInstanceToListItem( + durationEpoch: number, alert: Alert, instanceId: string, instance?: RawAlertInstance @@ -221,7 +233,10 @@ export function alertInstanceToListItem( ? { label: ACTIVE_LABEL, healthColor: 'primary' } : { label: INACTIVE_LABEL, healthColor: 'subdued' }, start: instance?.meta?.lastScheduledActions?.date, - duration: durationSince(instance?.meta?.lastScheduledActions?.date), + duration: durationSince( + durationEpoch, + instance?.meta?.lastScheduledActions?.date?.getTime() ?? 0 + ), isMuted, }; } diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts index 86fc3d6cd6a6c0..74a267c6e0a8e0 100644 --- a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts +++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts @@ -18,8 +18,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { const alerting = getService('alerting'); const retry = getService('retry'); - // FLAKY: https://github.com/elastic/kibana/issues/57426 - describe.skip('Alert Details', function() { + describe('Alert Details', function() { describe('Header', function() { const testRunUuid = uuid.v4(); before(async () => { @@ -206,8 +205,6 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { }); it('renders the active alert instances', async () => { - const testBeganAt = moment().utc(); - // Verify content await testSubjects.existOrFail('alertInstancesList'); @@ -219,30 +216,42 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { meta: { lastScheduledActions: { date }, }, - }) => moment(date).utc() + }) => date ); + log.debug(`API RESULT: ${JSON.stringify(dateOnAllInstances)}`); + const instancesList = await pageObjects.alertDetailsUI.getAlertInstancesList(); expect(instancesList.map(instance => omit(instance, 'duration'))).to.eql([ { instance: 'us-central', status: 'Active', - start: dateOnAllInstances['us-central'].format('D MMM YYYY @ HH:mm:ss'), + start: moment(dateOnAllInstances['us-central']) + .utc() + .format('D MMM YYYY @ HH:mm:ss'), }, { instance: 'us-east', status: 'Active', - start: dateOnAllInstances['us-east'].format('D MMM YYYY @ HH:mm:ss'), + start: moment(dateOnAllInstances['us-east']) + .utc() + .format('D MMM YYYY @ HH:mm:ss'), }, { instance: 'us-west', status: 'Active', - start: dateOnAllInstances['us-west'].format('D MMM YYYY @ HH:mm:ss'), + start: moment(dateOnAllInstances['us-west']) + .utc() + .format('D MMM YYYY @ HH:mm:ss'), }, ]); + const durationEpoch = moment( + await pageObjects.alertDetailsUI.getAlertInstanceDurationEpoch() + ).utc(); + const durationFromInstanceTillPageLoad = mapValues(dateOnAllInstances, date => - moment.duration(testBeganAt.diff(moment(date).utc())) + moment.duration(durationEpoch.diff(moment(date).utc())) ); instancesList .map(alertInstance => ({ diff --git a/x-pack/test/functional_with_es_ssl/page_objects/alert_details.ts b/x-pack/test/functional_with_es_ssl/page_objects/alert_details.ts index 900fe3237ffac0..ddd88cb8885342 100644 --- a/x-pack/test/functional_with_es_ssl/page_objects/alert_details.ts +++ b/x-pack/test/functional_with_es_ssl/page_objects/alert_details.ts @@ -54,6 +54,12 @@ export function AlertDetailsPageProvider({ getService }: FtrProviderContext) { }; }); }, + async getAlertInstanceDurationEpoch(): Promise { + const alertInstancesDurationEpoch = await find.byCssSelector( + 'input[data-test-subj="alertInstancesDurationEpoch"]' + ); + return parseInt(await alertInstancesDurationEpoch.getAttribute('value'), 10); + }, async clickAlertInstanceMuteButton(instance: string) { const muteAlertInstanceButton = await testSubjects.find( `muteAlertInstanceButton_${instance}`