From 80310d8d78ae9bdf6269298e8bd3055290b94e80 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Tue, 1 Nov 2022 10:01:29 +0100 Subject: [PATCH] [Synthetics] Step details page screenshot (#143452) Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../common/runtime_types/ping/ping.ts | 3 +- .../e2e/page_objects/synthetics_app.tsx | 2 +- .../browser_steps_list.tsx | 2 +- .../monitor_test_result/empty_thumbnail.tsx | 2 +- .../journey_step_image_popover.tsx | 33 ++++-- .../journey_step_screenshot_with_label.tsx | 2 +- .../common/screenshot/empty_image.tsx | 102 ++++++++++++++++++ .../common/screenshot/journey_screenshot.tsx | 39 +++++++ ...journey_step_screenshot_container.test.tsx | 2 +- .../journey_step_screenshot_container.tsx | 16 ++- .../monitor_details_portal.tsx | 8 +- .../hooks/use_journey_steps.tsx | 27 ++++- .../monitor_summary/test_runs_table.tsx | 39 +------ .../screenshot/last_successful_screenshot.tsx | 47 ++++++++ .../components/step_image.tsx | 90 ++++++++++++++++ .../hooks/use_step_detail_page.ts | 68 ++++++++++++ .../hooks/use_step_details_breadcrumbs.ts | 28 +++++ .../step_details_page/step_detail_page.tsx | 94 ++++++++++++++++ .../step_details_page/step_title.tsx | 26 +++++ .../contexts/synthetics_theme_context.tsx | 4 +- .../public/apps/synthetics/routes.tsx | 21 ++++ .../synthetics/utils/testing/rtl_helpers.tsx | 1 + .../components/monitor/monitor_title.test.tsx | 2 + .../monitor/ping_list/ping_list.test.tsx | 4 + .../monitor_status.bar.test.tsx | 1 + .../columns/monitor_status_column.test.tsx | 9 ++ .../monitor_list_drawer.test.tsx.snap | 5 + .../monitor_status_list.test.tsx | 6 ++ .../state/reducers/monitor_status.test.ts | 2 + .../requests/get_monitor_availability.test.ts | 7 ++ 30 files changed, 632 insertions(+), 60 deletions(-) create mode 100644 x-pack/plugins/synthetics/public/apps/synthetics/components/common/screenshot/empty_image.tsx create mode 100644 x-pack/plugins/synthetics/public/apps/synthetics/components/common/screenshot/journey_screenshot.tsx rename x-pack/plugins/synthetics/public/apps/synthetics/components/common/{monitor_test_result => screenshot}/journey_step_screenshot_container.test.tsx (98%) rename x-pack/plugins/synthetics/public/apps/synthetics/components/common/{monitor_test_result => screenshot}/journey_step_screenshot_container.tsx (89%) create mode 100644 x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/components/screenshot/last_successful_screenshot.tsx create mode 100644 x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/components/step_image.tsx create mode 100644 x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/hooks/use_step_detail_page.ts create mode 100644 x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/hooks/use_step_details_breadcrumbs.ts create mode 100644 x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/step_detail_page.tsx create mode 100644 x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/step_title.tsx diff --git a/x-pack/plugins/synthetics/common/runtime_types/ping/ping.ts b/x-pack/plugins/synthetics/common/runtime_types/ping/ping.ts index dc8ab97c5f1878..598a62265f1c2f 100644 --- a/x-pack/plugins/synthetics/common/runtime_types/ping/ping.ts +++ b/x-pack/plugins/synthetics/common/runtime_types/ping/ping.ts @@ -94,12 +94,12 @@ export const MonitorType = t.intersection([ id: t.string, status: t.string, type: t.string, + check_group: t.string, }), t.partial({ duration: t.type({ us: t.number, }), - check_group: t.string, ip: t.string, name: t.string, timespan: t.type({ @@ -268,6 +268,7 @@ export const makePing = (f: { status: f.status || 'up', duration: { us: f.duration || 100000 }, name: f.name, + check_group: 'myCheckGroup', }, ...(f.location ? { observer: { geo: { name: f.location } } } : {}), ...(f.url ? { url: { full: f.url } } : {}), diff --git a/x-pack/plugins/synthetics/e2e/page_objects/synthetics_app.tsx b/x-pack/plugins/synthetics/e2e/page_objects/synthetics_app.tsx index fc365abd823b92..66d086fcea9d7b 100644 --- a/x-pack/plugins/synthetics/e2e/page_objects/synthetics_app.tsx +++ b/x-pack/plugins/synthetics/e2e/page_objects/synthetics_app.tsx @@ -82,7 +82,7 @@ export function syntheticsAppPageProvider({ page, kibanaUrl }: { page: Page; kib async navigateToEditMonitor() { await this.clickByTestSubj('syntheticsMonitorListActions'); - await page.click('text=Edit'); + await page.click('text=Edit', { timeout: 2 * 60 * 1000 }); await this.findByText('Edit monitor'); }, diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/monitor_test_result/browser_steps_list.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/monitor_test_result/browser_steps_list.tsx index 81ecb7dc60027f..ebc6cc265dfa50 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/monitor_test_result/browser_steps_list.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/monitor_test_result/browser_steps_list.tsx @@ -103,7 +103,7 @@ export const BrowserStepsList = ({ steps, error, loading, showStepNumber = false aria-label={VIEW_DETAILS} title={VIEW_DETAILS} size="s" - href={`${basePath}/app/uptime/journey/${item.monitor.check_group}/step/${item.synthetics?.step?.index}`} + href={`${basePath}/app/synthetics/journey/${item.monitor.check_group}/step/${item.synthetics?.step?.index}`} target="_self" iconType="apmTrace" /> diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/monitor_test_result/empty_thumbnail.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/monitor_test_result/empty_thumbnail.tsx index bfc5851ade6191..38ab5c66acbae0 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/monitor_test_result/empty_thumbnail.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/monitor_test_result/empty_thumbnail.tsx @@ -15,7 +15,7 @@ export const THUMBNAIL_HEIGHT = 64; export const thumbnailStyle = css` padding: 0; - margin: 0; + margin: auto; width: ${THUMBNAIL_WIDTH}px; height: ${THUMBNAIL_HEIGHT}px; object-fit: contain; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/monitor_test_result/journey_step_image_popover.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/monitor_test_result/journey_step_image_popover.tsx index 48ff7237223fb4..dda8c5343eb085 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/monitor_test_result/journey_step_image_popover.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/monitor_test_result/journey_step_image_popover.tsx @@ -9,10 +9,13 @@ import React from 'react'; import { css } from '@emotion/react'; import { EuiImage, EuiPopover, useEuiTheme } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import { useRouteMatch } from 'react-router-dom'; +import { EmptyImage } from '../screenshot/empty_image'; import { ScreenshotRefImageData } from '../../../../../../common/runtime_types'; import { useCompositeImage } from '../../../hooks/use_composite_image'; import { EmptyThumbnail, thumbnailStyle } from './empty_thumbnail'; +import { STEP_DETAIL_ROUTE } from '../../../../../../common/constants'; const POPOVER_IMG_HEIGHT = 360; const POPOVER_IMG_WIDTH = 640; @@ -22,6 +25,7 @@ interface ScreenshotImageProps { imageCaption: JSX.Element; isStepFailed: boolean; isLoading: boolean; + asThumbnail?: boolean; } const ScreenshotThumbnail: React.FC = ({ @@ -30,6 +34,7 @@ const ScreenshotThumbnail: React.FC { return imageData ? ( - ) : ( + ) : asThumbnail ? ( + ) : ( + ); }; /** @@ -64,6 +71,7 @@ const RecomposedScreenshotImage: React.FC< setImageData, isStepFailed, isLoading, + asThumbnail, }) => { // initially an undefined URL value is passed to the image display, and a loading spinner is rendered. // `useCompositeImage` will call `setImageData` when the image is composited, and the updated `imageData` will display. @@ -76,6 +84,7 @@ const RecomposedScreenshotImage: React.FC< imageData={imageData} isStepFailed={isStepFailed} isLoading={isLoading} + asThumbnail={asThumbnail} /> ); }; @@ -88,6 +97,7 @@ export interface StepImagePopoverProps { isImagePopoverOpen: boolean; isStepFailed: boolean; isLoading: boolean; + asThumbnail?: boolean; } const JourneyStepImage: React.FC< @@ -104,6 +114,7 @@ const JourneyStepImage: React.FC< setImageData, isStepFailed, isLoading, + asThumbnail = true, }) => { if (imgSrc) { return ( @@ -113,6 +124,7 @@ const JourneyStepImage: React.FC< imageData={imageData} isStepFailed={isStepFailed} isLoading={isLoading} + asThumbnail={asThumbnail} /> ); } else if (imgRef) { @@ -125,6 +137,7 @@ const JourneyStepImage: React.FC< setImageData={setImageData} isStepFailed={isStepFailed} isLoading={isLoading} + asThumbnail={asThumbnail} /> ); } @@ -139,6 +152,7 @@ export const JourneyStepImagePopover: React.FC = ({ isImagePopoverOpen, isStepFailed, isLoading, + asThumbnail = true, }) => { const { euiTheme } = useEuiTheme(); @@ -158,12 +172,16 @@ export const JourneyStepImagePopover: React.FC = ({ const isImageLoading = isLoading || (!!imgRef && !imageData); + const isStepDetailPage = useRouteMatch(STEP_DETAIL_ROUTE)?.isExact; + + const thumbnailS = isStepDetailPage ? null : thumbnailStyle; + return ( = ({ imageData={imageData} isStepFailed={isStepFailed} isLoading={isImageLoading} + asThumbnail={asThumbnail} /> } isOpen={isImagePopoverOpen} @@ -195,12 +214,10 @@ export const JourneyStepImagePopover: React.FC = ({ object-fit: contain; `} /> + ) : asThumbnail ? ( + ) : ( - + )} ); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/monitor_test_result/journey_step_screenshot_with_label.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/monitor_test_result/journey_step_screenshot_with_label.tsx index 12dcd4db95f00b..f153aa07f2f4f2 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/monitor_test_result/journey_step_screenshot_with_label.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/monitor_test_result/journey_step_screenshot_with_label.tsx @@ -8,7 +8,7 @@ import React, { CSSProperties } from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiText, useEuiTheme } from '@elastic/eui'; import { JourneyStep } from '../../../../../../common/runtime_types'; -import { JourneyStepScreenshotContainer } from './journey_step_screenshot_container'; +import { JourneyStepScreenshotContainer } from '../screenshot/journey_step_screenshot_container'; import { getTextColorForMonitorStatus, parseBadgeStatus } from './status_badge'; interface Props { diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/screenshot/empty_image.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/screenshot/empty_image.tsx new file mode 100644 index 00000000000000..57295b3e1daf23 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/screenshot/empty_image.tsx @@ -0,0 +1,102 @@ +/* + * 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 React from 'react'; +import { css } from '@emotion/react'; +import { i18n } from '@kbn/i18n'; +import { + useEuiTheme, + useEuiBackgroundColor, + EuiIcon, + EuiLoadingContent, + EuiText, +} from '@elastic/eui'; + +export const IMAGE_WIDTH = 360; +export const IMAGE_HEIGHT = 203; + +export const imageStyle = css` + padding: 0; + margin: auto; + width: ${IMAGE_WIDTH}px; + height: ${IMAGE_HEIGHT}px; + object-fit: contain; + overflow: hidden; + display: flex; + align-items: center; + justify-content: center; +`; + +export const EmptyImage = ({ + isLoading = false, + width = IMAGE_WIDTH, + height = IMAGE_HEIGHT, +}: { + isLoading: boolean; + width?: number; + height?: number; +}) => { + const { euiTheme } = useEuiTheme(); + + return ( +
+ {isLoading ? ( + + ) : ( +
+ + {IMAGE_UN_AVAILABLE} +
+ )} +
+ ); +}; + +export const SCREENSHOT_LOADING_ARIA_LABEL = i18n.translate( + 'xpack.synthetics.monitor.step.screenshot.ariaLabel', + { + defaultMessage: 'Step screenshot is being loaded.', + } +); + +export const SCREENSHOT_NOT_AVAILABLE = i18n.translate( + 'xpack.synthetics.monitor.step.screenshot.notAvailable', + { + defaultMessage: 'Step screenshot is not available.', + } +); + +export const IMAGE_UN_AVAILABLE = i18n.translate( + 'xpack.synthetics.monitor.step.screenshot.unAvailable', + { + defaultMessage: 'Image unavailable', + } +); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/screenshot/journey_screenshot.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/screenshot/journey_screenshot.tsx new file mode 100644 index 00000000000000..9199c3f7db7e8e --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/screenshot/journey_screenshot.tsx @@ -0,0 +1,39 @@ +/* + * 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 React, { useMemo } from 'react'; +import { useJourneySteps } from '../../monitor_details/hooks/use_journey_steps'; +import { parseBadgeStatus } from '../monitor_test_result/status_badge'; +import { JourneyStepScreenshotContainer } from './journey_step_screenshot_container'; + +export const JourneyScreenshot = ({ checkGroupId }: { checkGroupId: string }) => { + const { loading: stepsLoading, stepEnds } = useJourneySteps(checkGroupId); + const stepLabels = stepEnds.map((stepEnd) => stepEnd?.synthetics?.step?.name ?? ''); + + const lastSignificantStep = useMemo(() => { + const copy = [...stepEnds]; + // Sort desc by timestamp + copy.sort( + (stepA, stepB) => + Number(new Date(stepB['@timestamp'])) - Number(new Date(stepA['@timestamp'])) + ); + return copy.find( + (stepEnd) => parseBadgeStatus(stepEnd?.synthetics?.step?.status ?? 'skipped') !== 'skipped' + ); + }, [stepEnds]); + + return ( + + ); +}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/monitor_test_result/journey_step_screenshot_container.test.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/screenshot/journey_step_screenshot_container.test.tsx similarity index 98% rename from x-pack/plugins/synthetics/public/apps/synthetics/components/common/monitor_test_result/journey_step_screenshot_container.test.tsx rename to x-pack/plugins/synthetics/public/apps/synthetics/components/common/screenshot/journey_step_screenshot_container.test.tsx index 4c95fade23d1a9..61219b57ae86d1 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/monitor_test_result/journey_step_screenshot_container.test.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/screenshot/journey_step_screenshot_container.test.tsx @@ -14,7 +14,7 @@ import * as observabilityPublic from '@kbn/observability-plugin/public'; import { getShortTimeStamp } from '../../../utils/monitor_test_result/timestamp'; import '../../../utils/testing/__mocks__/use_composite_image.mock'; import { mockRef } from '../../../utils/testing/__mocks__/screenshot_ref.mock'; -import * as retrieveHooks from './use_retrieve_step_image'; +import * as retrieveHooks from '../monitor_test_result/use_retrieve_step_image'; jest.mock('@kbn/observability-plugin/public'); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/monitor_test_result/journey_step_screenshot_container.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/screenshot/journey_step_screenshot_container.tsx similarity index 89% rename from x-pack/plugins/synthetics/public/apps/synthetics/components/common/monitor_test_result/journey_step_screenshot_container.tsx rename to x-pack/plugins/synthetics/public/apps/synthetics/components/common/screenshot/journey_step_screenshot_container.tsx index 6c2653f7efaa6b..24045d5ac458a7 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/monitor_test_result/journey_step_screenshot_container.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/screenshot/journey_step_screenshot_container.tsx @@ -10,6 +10,7 @@ import { css } from '@emotion/react'; import useIntersection from 'react-use/lib/useIntersection'; import { i18n } from '@kbn/i18n'; +import { EmptyImage } from './empty_image'; import { isScreenshotImageBlob, isScreenshotRef, @@ -18,10 +19,10 @@ import { import { SyntheticsSettingsContext } from '../../../contexts'; -import { useRetrieveStepImage } from './use_retrieve_step_image'; -import { ScreenshotOverlayFooter } from './screenshot_overlay_footer'; -import { JourneyStepImagePopover } from './journey_step_image_popover'; -import { EmptyThumbnail } from './empty_thumbnail'; +import { useRetrieveStepImage } from '../monitor_test_result/use_retrieve_step_image'; +import { ScreenshotOverlayFooter } from '../monitor_test_result/screenshot_overlay_footer'; +import { JourneyStepImagePopover } from '../monitor_test_result/journey_step_image_popover'; +import { EmptyThumbnail } from '../monitor_test_result/empty_thumbnail'; interface Props { checkGroup?: string; @@ -29,6 +30,7 @@ interface Props { stepStatus?: string; initialStepNo?: number; allStepsLoaded?: boolean; + asThumbnail?: boolean; retryFetchOnRevisit?: boolean; // Set to `true` fro "Run Once" / "Test Now" modes } @@ -39,6 +41,7 @@ export const JourneyStepScreenshotContainer = ({ allStepsLoaded, initialStepNo = 1, retryFetchOnRevisit = false, + asThumbnail = true, }: Props) => { const [stepNumber, setStepNumber] = useState(initialStepNo); const [isImagePopoverOpen, setIsImagePopoverOpen] = useState(false); @@ -135,9 +138,12 @@ export const JourneyStepScreenshotContainer = ({ isImagePopoverOpen={isImagePopoverOpen} isStepFailed={stepStatus === 'failed'} isLoading={Boolean(loading)} + asThumbnail={asThumbnail} /> - ) : ( + ) : asThumbnail ? ( + ) : ( + )} ); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/monitor_details_portal.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/monitor_details_portal.tsx index 950d439173004c..10de9f5a4c629f 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/monitor_details_portal.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_add_edit/monitor_details_portal.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { useHistory } from 'react-router-dom'; -import { EuiButtonEmpty } from '@elastic/eui'; +import { EuiLink, EuiIcon } from '@elastic/eui'; import { InPortal } from 'react-reverse-portal'; import { MonitorDetailsLinkPortalNode } from './portals'; @@ -25,8 +25,8 @@ export const MonitorDetailsLink = ({ name, id }: { name: string; id: string }) = pathname: `monitor/${id}`, }); return ( - - {name} - + + {name} + ); }; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/hooks/use_journey_steps.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/hooks/use_journey_steps.tsx index a6d2070d0e96a9..13f3d245947078 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/hooks/use_journey_steps.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/hooks/use_journey_steps.tsx @@ -6,10 +6,14 @@ */ import { useFetcher } from '@kbn/observability-plugin/public'; -import { SyntheticsJourneyApiResponse } from '../../../../../../common/runtime_types'; +import { useParams } from 'react-router-dom'; +import { isStepEnd } from '../../common/monitor_test_result/browser_steps_list'; +import { JourneyStep, SyntheticsJourneyApiResponse } from '../../../../../../common/runtime_types'; import { fetchJourneySteps } from '../../../state'; export const useJourneySteps = (checkGroup: string | undefined) => { + const { stepIndex } = useParams<{ stepIndex: string }>(); + const { data, loading } = useFetcher(() => { if (!checkGroup) { return Promise.resolve(null); @@ -18,5 +22,24 @@ export const useJourneySteps = (checkGroup: string | undefined) => { return fetchJourneySteps({ checkGroup }); }, [checkGroup]); - return { data: data as SyntheticsJourneyApiResponse, loading: loading ?? false }; + const isFailed = + data?.steps.some( + (step) => + step.synthetics?.step?.status === 'failed' || step.synthetics?.step?.status === 'skipped' + ) ?? false; + + const stepEnds: JourneyStep[] = (data?.steps ?? []).filter(isStepEnd); + + const stepLabels = stepEnds.map((stepEnd) => stepEnd?.synthetics?.step?.name ?? ''); + + return { + data: data as SyntheticsJourneyApiResponse, + loading: loading ?? false, + isFailed, + stepEnds, + stepLabels, + currentStep: stepIndex + ? data?.steps.find((step) => step.synthetics?.step?.index === Number(stepIndex)) + : undefined, + }; }; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_summary/test_runs_table.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_summary/test_runs_table.tsx index 00ef508ed0d2c8..891d1694de4bce 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_summary/test_runs_table.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_summary/test_runs_table.tsx @@ -23,7 +23,7 @@ import { import { Criteria } from '@elastic/eui/src/components/basic_table/basic_table'; import { EuiTableSortingType } from '@elastic/eui/src/components/basic_table/table_types'; -import { ConfigKey, DataStream, JourneyStep, Ping } from '../../../../../../common/runtime_types'; +import { ConfigKey, DataStream, Ping } from '../../../../../../common/runtime_types'; import { formatTestDuration, formatTestRunAt, @@ -33,13 +33,11 @@ import { useSyntheticsSettingsContext } from '../../../contexts/synthetics_setti import { sortPings } from '../../../utils/monitor_test_result/sort_pings'; import { selectPingsError } from '../../../state'; import { parseBadgeStatus, StatusBadge } from '../../common/monitor_test_result/status_badge'; -import { isStepEnd } from '../../common/monitor_test_result/browser_steps_list'; -import { JourneyStepScreenshotContainer } from '../../common/monitor_test_result/journey_step_screenshot_container'; import { useKibanaDateFormat } from '../../../../../hooks/use_kibana_date_format'; import { useSelectedMonitor } from '../hooks/use_selected_monitor'; import { useMonitorPings } from '../hooks/use_monitor_pings'; -import { useJourneySteps } from '../hooks/use_journey_steps'; +import { JourneyScreenshot } from '../../common/screenshot/journey_screenshot'; type SortableField = 'timestamp' | 'monitor.status' | 'monitor.duration.us'; @@ -98,7 +96,9 @@ export const TestRunsTable = ({ paginable = true, from, to }: TestRunsTableProps align: 'left', field: 'timestamp', name: SCREENSHOT_LABEL, - render: (_timestamp: string, item) => , + render: (_timestamp: string, item) => ( + + ), }, ] : []) as Array>), @@ -197,35 +197,6 @@ export const TestRunsTable = ({ paginable = true, from, to }: TestRunsTableProps ); }; -const JourneyScreenshot = ({ ping }: { ping: Ping }) => { - const { data: stepsData, loading: stepsLoading } = useJourneySteps(ping?.monitor?.check_group); - const stepEnds: JourneyStep[] = (stepsData?.steps ?? []).filter(isStepEnd); - const stepLabels = stepEnds.map((stepEnd) => stepEnd?.synthetics?.step?.name ?? ''); - - const lastSignificantStep = useMemo(() => { - const copy = [...stepEnds]; - // Sort desc by timestamp - copy.sort( - (stepA, stepB) => - Number(new Date(stepB['@timestamp'])) - Number(new Date(stepA['@timestamp'])) - ); - return copy.find( - (stepEnd) => parseBadgeStatus(stepEnd?.synthetics?.step?.status ?? 'skipped') !== 'skipped' - ); - }, [stepEnds]); - - return ( - - ); -}; - const TestDetailsLink = ({ isBrowserMonitor, timestamp, diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/components/screenshot/last_successful_screenshot.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/components/screenshot/last_successful_screenshot.tsx new file mode 100644 index 00000000000000..3874d29197d3cd --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/components/screenshot/last_successful_screenshot.tsx @@ -0,0 +1,47 @@ +/* + * 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 { useFetcher } from '@kbn/observability-plugin/public'; +import { EuiSpacer } from '@elastic/eui'; +import React from 'react'; +import { useParams } from 'react-router-dom'; +import { fetchLastSuccessfulCheck } from '../../../../state'; +import { JourneyStep } from '../../../../../../../common/runtime_types'; +import { EmptyImage } from '../../../common/screenshot/empty_image'; +import { JourneyStepScreenshotContainer } from '../../../common/screenshot/journey_step_screenshot_container'; + +export const LastSuccessfulScreenshot = ({ step }: { step: JourneyStep }) => { + const { stepIndex } = useParams<{ checkGroupId: string; stepIndex: string }>(); + + const { data, loading } = useFetcher(() => { + return fetchLastSuccessfulCheck({ + timestamp: step['@timestamp'], + monitorId: step.monitor.id, + stepIndex: Number(stepIndex), + location: step.observer?.geo?.name, + }); + }, [step._id, step['@timestamp']]); + + if (loading || !data) { + return ; + } + + return ( + <> + + + + ); +}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/components/step_image.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/components/step_image.tsx new file mode 100644 index 00000000000000..a08ba79444ccb0 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/components/step_image.tsx @@ -0,0 +1,90 @@ +/* + * 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 React, { useState } from 'react'; +import { EuiButtonGroup, EuiSpacer, EuiTitle } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { LastSuccessfulScreenshot } from './screenshot/last_successful_screenshot'; +import { JourneyStep } from '../../../../../../common/runtime_types'; +import { JourneyStepScreenshotContainer } from '../../common/screenshot/journey_step_screenshot_container'; + +export const StepImage = ({ + step, + ping, + isFailed, + stepLabels, +}: { + ping: JourneyStep; + step: JourneyStep; + isFailed?: boolean; + stepLabels?: string[]; +}) => { + const toggleButtons = [ + { + id: `received`, + label: RECEIVED_LABEL, + }, + { + id: `expected`, + label: EXPECTED_LABEL, + }, + ]; + + const [idSelected, setIdSelected] = useState(`received`); + + const onChangeDisabled = (optionId: string) => { + setIdSelected(optionId); + }; + + return ( + <> + +

{SCREENSHOT_LABEL}

+
+ +
+ {idSelected === 'received' ? ( + + ) : ( + + )} + + + {isFailed && ( + onChangeDisabled(id)} + buttonSize="s" + isFullWidth + /> + )} +
+ + ); +}; + +const SCREENSHOT_LABEL = i18n.translate('xpack.synthetics.stepDetails.screenshot', { + defaultMessage: 'Screenshot', +}); + +const EXPECTED_LABEL = i18n.translate('xpack.synthetics.stepDetails.expected', { + defaultMessage: 'Expected', +}); + +const RECEIVED_LABEL = i18n.translate('xpack.synthetics.stepDetails.received', { + defaultMessage: 'Received', +}); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/hooks/use_step_detail_page.ts b/x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/hooks/use_step_detail_page.ts new file mode 100644 index 00000000000000..4c79502ce665f3 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/hooks/use_step_detail_page.ts @@ -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 { useParams } from 'react-router-dom'; +import { useMemo } from 'react'; +import { useSyntheticsSettingsContext } from '../../../contexts'; +import { useJourneySteps } from '../../monitor_details/hooks/use_journey_steps'; +import { JourneyStep, SyntheticsJourneyApiResponse } from '../../../../../../common/runtime_types'; + +export const useStepDetailPage = (): { + activeStep?: JourneyStep; + checkGroupId: string; + handleNextStepHref: string; + handlePreviousStepHref: string; + handleNextRunHref: string; + handlePreviousRunHref: string; + hasNextStep: boolean; + hasPreviousStep: boolean; + journey?: SyntheticsJourneyApiResponse; + stepIndex: number; +} => { + const { checkGroupId, stepIndex: stepIndexString } = useParams<{ + checkGroupId: string; + stepIndex: string; + }>(); + + const stepIndex = Number(stepIndexString); + + const { data: journey } = useJourneySteps(checkGroupId); + + const memoized = useMemo( + () => ({ + hasPreviousStep: stepIndex > 1 ? true : false, + activeStep: journey?.steps?.find((step) => step.synthetics?.step?.index === stepIndex), + hasNextStep: journey && journey.steps && stepIndex < journey.steps.length ? true : false, + }), + [journey, stepIndex] + ); + + const { basePath } = useSyntheticsSettingsContext(); + + const handleNextStepHref = `${basePath}/app/synthetics/journey/${checkGroupId}/step/${ + stepIndex + 1 + }`; + + const handlePreviousStepHref = `${basePath}/app/synthetics/journey/${checkGroupId}/step/${ + stepIndex - 1 + }`; + + const handleNextRunHref = `${basePath}/app/synthetics/journey/${journey?.details?.next?.checkGroup}/step/1`; + + const handlePreviousRunHref = `${basePath}/app/synthetics/journey/${journey?.details?.previous?.checkGroup}/step/1`; + + return { + checkGroupId, + journey, + stepIndex, + ...memoized, + handleNextStepHref, + handlePreviousStepHref, + handleNextRunHref, + handlePreviousRunHref, + }; +}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/hooks/use_step_details_breadcrumbs.ts b/x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/hooks/use_step_details_breadcrumbs.ts new file mode 100644 index 00000000000000..b42417083cc3a4 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/hooks/use_step_details_breadcrumbs.ts @@ -0,0 +1,28 @@ +/* + * 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 { i18n } from '@kbn/i18n'; +import { useKibana } from '@kbn/kibana-react-plugin/public'; +import { useBreadcrumbs } from '../../../hooks/use_breadcrumbs'; +import { MONITORS_ROUTE } from '../../../../../../common/constants'; +import { PLUGIN } from '../../../../../../common/constants/plugin'; + +export const useStepDetailsBreadcrumbs = (extraCrumbs?: Array<{ text: string; href?: string }>) => { + const kibana = useKibana(); + const appPath = kibana.services.application?.getUrlForApp(PLUGIN.SYNTHETICS_PLUGIN_ID) ?? ''; + + useBreadcrumbs([ + { + text: MONITOR_MANAGEMENT_CRUMB, + href: `${appPath}/${MONITORS_ROUTE}`, + }, + ...(extraCrumbs ?? []), + ]); +}; + +const MONITOR_MANAGEMENT_CRUMB = i18n.translate('xpack.synthetics.monitorsPage.monitorsMCrumb', { + defaultMessage: 'Monitors', +}); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/step_detail_page.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/step_detail_page.tsx new file mode 100644 index 00000000000000..09122158e45ed0 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/step_detail_page.tsx @@ -0,0 +1,94 @@ +/* + * 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 React from 'react'; +import { useParams } from 'react-router-dom'; +import { useTrackPageview } from '@kbn/observability-plugin/public'; +import { + EuiFlexGroup, + EuiFlexItem, + EuiHorizontalRule, + EuiPanel, + EuiLoadingSpinner, +} from '@elastic/eui'; +import { StepImage } from './components/step_image'; +import { useJourneySteps } from '../monitor_details/hooks/use_journey_steps'; +import { MonitorDetailsLinkPortal } from '../monitor_add_edit/monitor_details_portal'; +import { useStepDetailsBreadcrumbs } from './hooks/use_step_details_breadcrumbs'; + +export const StepDetailPage = () => { + const { checkGroupId } = useParams<{ checkGroupId: string; stepIndex: string }>(); + + useTrackPageview({ app: 'synthetics', path: 'stepDetail' }); + useTrackPageview({ app: 'synthetics', path: 'stepDetail', delay: 15000 }); + + const { data, loading, isFailed, currentStep, stepLabels } = useJourneySteps(checkGroupId); + + useStepDetailsBreadcrumbs([{ text: data?.details?.journey.monitor.name ?? '' }]); + + if (loading) { + return ( +
+ +
+ ); + } + + return ( + <> + {data?.details?.journey && ( + + )} + + + + {data?.details?.journey && currentStep && ( + + )} + + + + + + + {/* TODO: Add breakdown of network timings donut*/} + + + {/* TODO: Add breakdown of network events*/} + + + + + + + + {/* TODO: Add step metrics*/} + + + + + + {/* TODO: Add breakdown of object list*/} + + {/* TODO: Add breakdown of object weight*/} + + + + + + {/* TODO: Add breakdown of network events*/} + + ); +}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/step_title.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/step_title.tsx new file mode 100644 index 00000000000000..5cb758e4b3d370 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/step_details_page/step_title.tsx @@ -0,0 +1,26 @@ +/* + * 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 React from 'react'; +import { useParams } from 'react-router-dom'; +import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { useJourneySteps } from '../monitor_details/hooks/use_journey_steps'; + +export const StepTitle = () => { + const { checkGroupId, stepIndex } = useParams<{ checkGroupId: string; stepIndex: string }>(); + + const { data } = useJourneySteps(checkGroupId); + + const currentStep = data?.steps.find((step) => step.synthetics.step?.index === Number(stepIndex)); + + return ( + + {currentStep?.synthetics?.step?.name} + + + ); +}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/contexts/synthetics_theme_context.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/contexts/synthetics_theme_context.tsx index 32844de9d04c2a..1415b1076cdd9d 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/contexts/synthetics_theme_context.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/contexts/synthetics_theme_context.tsx @@ -6,7 +6,7 @@ */ import { euiLightVars, euiDarkVars } from '@kbn/ui-theme'; -import React, { createContext, useMemo } from 'react'; +import React, { createContext, useContext, useMemo } from 'react'; import { EUI_CHARTS_THEME_DARK, EUI_CHARTS_THEME_LIGHT } from '@elastic/eui/dist/eui_charts_theme'; import { DARK_THEME, LIGHT_THEME, PartialTheme, Theme } from '@elastic/charts'; @@ -96,3 +96,5 @@ export const SyntheticsThemeContextProvider: React.FC = ({ return ; }; + +export const useSyntheticsThemeContext = () => useContext(SyntheticsThemeContext); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/routes.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/routes.tsx index 6319610f8e8c79..06b684dd307195 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/routes.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/routes.tsx @@ -24,6 +24,7 @@ import { useKibana } from '@kbn/kibana-react-plugin/public'; import { useInspectorContext } from '@kbn/observability-plugin/public'; import type { LazyObservabilityPageTemplateProps } from '@kbn/observability-plugin/public'; import { ErrorDetailsPage } from './components/error_details/error_details_page'; +import { StepTitle } from './components/step_details_page/step_title'; import { MonitorAddPage } from './components/monitor_add_edit/monitor_add_page'; import { MonitorEditPage } from './components/monitor_add_edit/monitor_edit_page'; import { MonitorDetailsPageTitle } from './components/monitor_details/monitor_details_page_title'; @@ -46,6 +47,7 @@ import { MONITOR_ERRORS_ROUTE, MONITOR_HISTORY_ROUTE, MONITOR_ROUTE, + STEP_DETAIL_ROUTE, ERROR_DETAILS_ROUTE, OVERVIEW_ROUTE, } from '../../../common/constants'; @@ -59,6 +61,7 @@ import { MonitorDetailsLastRun } from './components/monitor_details/monitor_deta import { MonitorSummary } from './components/monitor_details/monitor_summary/monitor_summary'; import { MonitorHistory } from './components/monitor_details/monitor_history/monitor_history'; import { MonitorErrors } from './components/monitor_details/monitor_errors/monitor_errors'; +import { StepDetailPage } from './components/step_details_page/step_detail_page'; type RouteProps = LazyObservabilityPageTemplateProps & { path: string; @@ -285,6 +288,24 @@ const getRoutes = ( ], }, }, + { + title: i18n.translate('xpack.synthetics.stepDetailsRoute.title', { + defaultMessage: 'Step details | {baseTitle}', + values: { baseTitle }, + }), + path: STEP_DETAIL_ROUTE, + component: () => , + dataTestSubj: 'syntheticsMonitorEditPage', + pageHeader: { + pageTitle: , + rightSideItems: [], + breadcrumbs: [ + { + text: , + }, + ], + }, + }, { title: i18n.translate('xpack.synthetics.errorDetailsRoute.title', { defaultMessage: 'Error details | {baseTitle}', diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/utils/testing/rtl_helpers.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/utils/testing/rtl_helpers.tsx index 55ae549a032b34..3168c1b07ee337 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/utils/testing/rtl_helpers.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/utils/testing/rtl_helpers.tsx @@ -95,6 +95,7 @@ const createMockStore = () => { const mockAppUrls: Record = { uptime: '/app/uptime', + synthetics: '/app/synthetics', observability: '/app/observability', '/home#/tutorial/uptimeMonitors': '/home#/tutorial/uptimeMonitors', }; diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/monitor_title.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/monitor_title.test.tsx index f9e3572ead5111..e4594e8c60630e 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/monitor_title.test.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/monitor_title.test.tsx @@ -42,6 +42,7 @@ describe('MonitorTitle component', () => { id: defaultMonitorId, status: 'up', type: 'http', + check_group: 'test-group', }, url: { full: 'https://www.elastic.co/', @@ -58,6 +59,7 @@ describe('MonitorTitle component', () => { id: 'browser', status: 'up', type: 'browser', + check_group: 'test-group', }, url: { full: 'https://www.elastic.co/', diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/ping_list.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/ping_list.test.tsx index ddb33e4dd5feaf..f0e60b29028282 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/ping_list.test.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/ping_list/ping_list.test.tsx @@ -32,6 +32,7 @@ describe('PingList component', () => { name: '', status: 'down', type: 'tcp', + check_group: 'test-group', }, }, { @@ -47,6 +48,7 @@ describe('PingList component', () => { name: '', status: 'down', type: 'tcp', + check_group: 'test-group', }, }, ]; @@ -120,6 +122,7 @@ describe('PingList component', () => { "type": "io", }, "monitor": Object { + "check_group": "test-group", "duration": Object { "us": 1430, }, @@ -160,6 +163,7 @@ describe('PingList component', () => { "type": "io", }, "monitor": Object { + "check_group": "test-group", "id": "auto-tcp-0X81440A68E839814D", "ip": "255.255.255.0", "name": "", diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/status_details/monitor_status.bar.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/status_details/monitor_status.bar.test.tsx index 640d207fbb1384..af5df91160026a 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/status_details/monitor_status.bar.test.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/monitor/status_details/monitor_status.bar.test.tsx @@ -28,6 +28,7 @@ describe('MonitorStatusBar component', () => { id: 'id1', status: 'up', type: 'http', + check_group: 'test-group', }, url: { full: 'https://www.example.com/', diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/monitor_list/columns/monitor_status_column.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/monitor_list/columns/monitor_status_column.test.tsx index a69ebb3d349fdf..7869125014b02a 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/monitor_list/columns/monitor_status_column.test.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/monitor_list/columns/monitor_status_column.test.tsx @@ -37,6 +37,7 @@ describe('MonitorListStatusColumn', () => { id: 'myMonitor', type: 'icmp', duration: { us: 123 }, + check_group: 'test-group', }, observer: { geo: { @@ -58,6 +59,7 @@ describe('MonitorListStatusColumn', () => { id: 'myMonitor', type: 'icmp', duration: { us: 123 }, + check_group: 'test-group', }, observer: { geo: { @@ -79,6 +81,7 @@ describe('MonitorListStatusColumn', () => { id: 'myMonitor', type: 'icmp', duration: { us: 123 }, + check_group: 'test-group', }, observer: { geo: { @@ -103,6 +106,7 @@ describe('MonitorListStatusColumn', () => { id: 'myMonitor', type: 'icmp', duration: { us: 123 }, + check_group: 'test-group', }, observer: { geo: { @@ -124,6 +128,7 @@ describe('MonitorListStatusColumn', () => { id: 'myMonitor', type: 'icmp', duration: { us: 123 }, + check_group: 'test-group', }, observer: { geo: { @@ -145,6 +150,7 @@ describe('MonitorListStatusColumn', () => { id: 'myMonitor', type: 'icmp', duration: { us: 123 }, + check_group: 'test-group', }, observer: { geo: { @@ -169,6 +175,7 @@ describe('MonitorListStatusColumn', () => { id: 'myMonitor', type: 'icmp', duration: { us: 123 }, + check_group: 'test-group', }, observer: { geo: { @@ -190,6 +197,7 @@ describe('MonitorListStatusColumn', () => { id: 'myMonitor', type: 'icmp', duration: { us: 123 }, + check_group: 'test-group', }, observer: { geo: { @@ -211,6 +219,7 @@ describe('MonitorListStatusColumn', () => { id: 'myMonitor', type: 'icmp', duration: { us: 123 }, + check_group: 'test-group', }, observer: { geo: { diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/monitor_list/monitor_list_drawer/__snapshots__/monitor_list_drawer.test.tsx.snap b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/monitor_list/monitor_list_drawer/__snapshots__/monitor_list_drawer.test.tsx.snap index a07a55df6dbfaf..0c037492bbc6be 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/monitor_list/monitor_list_drawer/__snapshots__/monitor_list_drawer.test.tsx.snap +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/monitor_list/monitor_list_drawer/__snapshots__/monitor_list_drawer.test.tsx.snap @@ -111,6 +111,7 @@ exports[`MonitorListDrawer component renders a MonitorListDrawer when there are Object { "docId": "foo", "monitor": Object { + "check_group": "myCheckGroup", "duration": Object { "us": 121, }, @@ -125,6 +126,7 @@ exports[`MonitorListDrawer component renders a MonitorListDrawer when there are Object { "docId": "foo-0", "monitor": Object { + "check_group": "myCheckGroup", "duration": Object { "us": 100000, }, @@ -139,6 +141,7 @@ exports[`MonitorListDrawer component renders a MonitorListDrawer when there are Object { "docId": "foo-1", "monitor": Object { + "check_group": "myCheckGroup", "duration": Object { "us": 1, }, @@ -153,6 +156,7 @@ exports[`MonitorListDrawer component renders a MonitorListDrawer when there are Object { "docId": "foo-2", "monitor": Object { + "check_group": "myCheckGroup", "duration": Object { "us": 2, }, @@ -289,6 +293,7 @@ exports[`MonitorListDrawer component renders a MonitorListDrawer when there is o Object { "docId": "foo", "monitor": Object { + "check_group": "myCheckGroup", "duration": Object { "us": 121, }, diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/monitor_list/monitor_list_drawer/monitor_status_list.test.tsx b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/monitor_list/monitor_list_drawer/monitor_status_list.test.tsx index f1a9d1b2629a6b..7318fc5188af82 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/monitor_list/monitor_list_drawer/monitor_status_list.test.tsx +++ b/x-pack/plugins/synthetics/public/legacy_uptime/components/overview/monitor_list/monitor_list_drawer/monitor_status_list.test.tsx @@ -29,6 +29,7 @@ describe('MonitorStatusList component', () => { id: 'myMonitor', type: 'icmp', duration: { us: 123 }, + check_group: 'test-group', }, observer: { geo: {}, @@ -44,6 +45,7 @@ describe('MonitorStatusList component', () => { id: 'myMonitor', type: 'icmp', duration: { us: 123 }, + check_group: 'test-group', }, observer: { geo: {}, @@ -59,6 +61,7 @@ describe('MonitorStatusList component', () => { id: 'myUpMonitor', type: 'icmp', duration: { us: 234 }, + check_group: 'test-group', }, observer: { geo: { @@ -165,6 +168,7 @@ describe('MonitorStatusList component', () => { id: 'myMonitor', type: 'icmp', duration: { us: 234 }, + check_group: 'test-group', }, observer: { geo: { @@ -182,6 +186,7 @@ describe('MonitorStatusList component', () => { id: 'myMonitor', type: 'icmp', duration: { us: 234 }, + check_group: 'test-group', }, observer: { geo: { @@ -199,6 +204,7 @@ describe('MonitorStatusList component', () => { id: 'myMonitor', type: 'icmp', duration: { us: 234 }, + check_group: 'test-group', }, observer: { geo: { diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/monitor_status.test.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/monitor_status.test.ts index f6c637e5fdb1b2..c7675d96077723 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/monitor_status.test.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/reducers/monitor_status.test.ts @@ -25,6 +25,7 @@ describe('selectedFiltersReducer', () => { us: 1, }, type: 'browser', + check_group: 'test-group', }, }, }; @@ -42,6 +43,7 @@ describe('selectedFiltersReducer', () => { us: 1, }, type: 'browser', + check_group: 'test-group', }, }; expect( diff --git a/x-pack/plugins/synthetics/server/legacy_uptime/lib/requests/get_monitor_availability.test.ts b/x-pack/plugins/synthetics/server/legacy_uptime/lib/requests/get_monitor_availability.test.ts index d84c4025d5dd07..7069cfce177409 100644 --- a/x-pack/plugins/synthetics/server/legacy_uptime/lib/requests/get_monitor_availability.test.ts +++ b/x-pack/plugins/synthetics/server/legacy_uptime/lib/requests/get_monitor_availability.test.ts @@ -411,6 +411,7 @@ describe('monitor availability', () => { "monitorInfo": Object { "docId": "myDocId", "monitor": Object { + "check_group": "myCheckGroup", "duration": Object { "us": 100000, }, @@ -432,6 +433,7 @@ describe('monitor availability', () => { "monitorInfo": Object { "docId": "myDocId", "monitor": Object { + "check_group": "myCheckGroup", "duration": Object { "us": 100000, }, @@ -453,6 +455,7 @@ describe('monitor availability', () => { "monitorInfo": Object { "docId": "myDocId", "monitor": Object { + "check_group": "myCheckGroup", "duration": Object { "us": 100000, }, @@ -542,6 +545,7 @@ describe('monitor availability', () => { "monitorInfo": Object { "docId": "myDocId", "monitor": Object { + "check_group": "myCheckGroup", "duration": Object { "us": 100000, }, @@ -563,6 +567,7 @@ describe('monitor availability', () => { "monitorInfo": Object { "docId": "myDocId", "monitor": Object { + "check_group": "myCheckGroup", "duration": Object { "us": 100000, }, @@ -584,6 +589,7 @@ describe('monitor availability', () => { "monitorInfo": Object { "docId": "myDocId", "monitor": Object { + "check_group": "myCheckGroup", "duration": Object { "us": 100000, }, @@ -605,6 +611,7 @@ describe('monitor availability', () => { "monitorInfo": Object { "docId": "myDocId", "monitor": Object { + "check_group": "myCheckGroup", "duration": Object { "us": 100000, },