From c24318ae407376a2528fcf6339e67fcc36f7a8c3 Mon Sep 17 00:00:00 2001 From: Steph Milovic Date: Tue, 29 Jun 2021 13:53:56 -0600 Subject: [PATCH] [RAC] [Cases] All cases table column design updates (#103544) --- .../public/components/all_cases/actions.tsx | 85 ++---------- .../all_cases/all_cases_generic.test.tsx | 18 +++ .../all_cases/all_cases_generic.tsx | 1 + .../components/all_cases/columns.test.tsx | 19 +++ .../public/components/all_cases/columns.tsx | 108 ++++++++------- .../components/all_cases/index.test.tsx | 124 +++++------------- .../components/all_cases/translations.ts | 13 +- .../case_action_bar/status_context_menu.tsx | 24 ++-- .../components/edit_connector/index.test.tsx | 5 + .../components/edit_connector/index.tsx | 14 +- .../plugins/cases/public/containers/mock.ts | 12 ++ .../server/scripts/mock/case/post_case.json | 3 +- .../observability_security.ts | 2 + 13 files changed, 194 insertions(+), 234 deletions(-) diff --git a/x-pack/plugins/cases/public/components/all_cases/actions.tsx b/x-pack/plugins/cases/public/components/all_cases/actions.tsx index 4820b10308934..d9e0e0ef025c8 100644 --- a/x-pack/plugins/cases/public/components/all_cases/actions.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/actions.tsx @@ -5,87 +5,24 @@ * 2.0. */ -import { Dispatch } from 'react'; import { DefaultItemIconButtonAction } from '@elastic/eui/src/components/basic_table/action_types'; -import { CaseStatuses } from '../../../common'; -import { Case, SubCase } from '../../containers/types'; -import { UpdateCase } from '../../containers/use_get_cases'; -import { statuses } from '../status'; +import { Case } from '../../containers/types'; import * as i18n from './translations'; -import { isIndividual } from './helpers'; interface GetActions { - dispatchUpdate: Dispatch>; deleteCaseOnClick: (deleteCase: Case) => void; } export const getActions = ({ - dispatchUpdate, deleteCaseOnClick, -}: GetActions): Array> => { - const openCaseAction = { - available: (item: Case | SubCase) => item.status !== CaseStatuses.open, - enabled: (item: Case | SubCase) => isIndividual(item), - description: statuses[CaseStatuses.open].actions.single.title, - icon: statuses[CaseStatuses.open].icon, - name: statuses[CaseStatuses.open].actions.single.title, - onClick: (theCase: Case) => - dispatchUpdate({ - updateKey: 'status', - updateValue: CaseStatuses.open, - caseId: theCase.id, - version: theCase.version, - }), - type: 'icon' as const, - 'data-test-subj': 'action-open', - }; - - const makeInProgressAction = { - available: (item: Case) => item.status !== CaseStatuses['in-progress'], - enabled: (item: Case | SubCase) => isIndividual(item), - description: statuses[CaseStatuses['in-progress']].actions.single.title, - icon: statuses[CaseStatuses['in-progress']].icon, - name: statuses[CaseStatuses['in-progress']].actions.single.title, - onClick: (theCase: Case) => - dispatchUpdate({ - updateKey: 'status', - updateValue: CaseStatuses['in-progress'], - caseId: theCase.id, - version: theCase.version, - }), - type: 'icon' as const, - 'data-test-subj': 'action-in-progress', - }; - - const closeCaseAction = { - available: (item: Case | SubCase) => item.status !== CaseStatuses.closed, - enabled: (item: Case | SubCase) => isIndividual(item), - description: statuses[CaseStatuses.closed].actions.single.title, - icon: statuses[CaseStatuses.closed].icon, - name: statuses[CaseStatuses.closed].actions.single.title, - onClick: (theCase: Case) => - dispatchUpdate({ - updateKey: 'status', - updateValue: CaseStatuses.closed, - caseId: theCase.id, - version: theCase.version, - }), - type: 'icon' as const, - 'data-test-subj': 'action-close', - }; - - return [ - openCaseAction, - makeInProgressAction, - closeCaseAction, - { - description: i18n.DELETE_CASE(), - icon: 'trash', - name: i18n.DELETE_CASE(), - onClick: deleteCaseOnClick, - type: 'icon', - 'data-test-subj': 'action-delete', - }, - ]; -}; +}: GetActions): Array> => [ + { + description: i18n.DELETE_CASE(), + icon: 'trash', + name: i18n.DELETE_CASE(), + onClick: deleteCaseOnClick, + type: 'icon', + 'data-test-subj': 'action-delete', + }, +]; diff --git a/x-pack/plugins/cases/public/components/all_cases/all_cases_generic.test.tsx b/x-pack/plugins/cases/public/components/all_cases/all_cases_generic.test.tsx index a0a5bb08ef770..47c683becb244 100644 --- a/x-pack/plugins/cases/public/components/all_cases/all_cases_generic.test.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/all_cases_generic.test.tsx @@ -34,6 +34,24 @@ const alertDataMock = { alertId: 'alert-id', owner: SECURITY_SOLUTION_OWNER, }; +jest.mock('../../common/lib/kibana', () => { + const originalModule = jest.requireActual('../../common/lib/kibana'); + return { + ...originalModule, + useKibana: () => ({ + services: { + triggersActionsUi: { + actionTypeRegistry: { + get: jest.fn().mockReturnValue({ + actionTypeTitle: '.jira', + iconClass: 'logoSecurity', + }), + }, + }, + }, + }), + }; +}); describe('AllCasesGeneric ', () => { beforeEach(() => { diff --git a/x-pack/plugins/cases/public/components/all_cases/all_cases_generic.tsx b/x-pack/plugins/cases/public/components/all_cases/all_cases_generic.tsx index 308c2186b52ed..a6d8afc3b8b23 100644 --- a/x-pack/plugins/cases/public/components/all_cases/all_cases_generic.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/all_cases_generic.tsx @@ -199,6 +199,7 @@ export const AllCasesGeneric = React.memo( isLoadingCases: loading, refreshCases, showActions, + userCanCrud, }); const itemIdToExpandedRowMap = useMemo( diff --git a/x-pack/plugins/cases/public/components/all_cases/columns.test.tsx b/x-pack/plugins/cases/public/components/all_cases/columns.test.tsx index c7a255da9dda6..0f0189f2d29c2 100644 --- a/x-pack/plugins/cases/public/components/all_cases/columns.test.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/columns.test.tsx @@ -13,6 +13,25 @@ import { ExternalServiceColumn } from './columns'; import { useGetCasesMockState } from '../../containers/mock'; +jest.mock('../../common/lib/kibana', () => { + const originalModule = jest.requireActual('../../common/lib/kibana'); + return { + ...originalModule, + useKibana: () => ({ + services: { + triggersActionsUi: { + actionTypeRegistry: { + get: jest.fn().mockReturnValue({ + actionTypeTitle: '.jira', + iconClass: 'logoSecurity', + }), + }, + }, + }, + }), + }; +}); + describe('ExternalServiceColumn ', () => { it('Not pushed render', () => { const wrapper = mount( diff --git a/x-pack/plugins/cases/public/components/all_cases/columns.tsx b/x-pack/plugins/cases/public/components/all_cases/columns.tsx index a5a299851d975..ad4447223837c 100644 --- a/x-pack/plugins/cases/public/components/all_cases/columns.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/columns.tsx @@ -16,6 +16,7 @@ import { EuiTableFieldDataColumnType, EuiFlexGroup, EuiFlexItem, + EuiIcon, } from '@elastic/eui'; import { RIGHT_ALIGNMENT } from '@elastic/eui/lib/services'; import styled from 'styled-components'; @@ -25,13 +26,14 @@ import { getEmptyTagValue } from '../empty_value'; import { FormattedRelativePreferenceDate } from '../formatted_date'; import { CaseDetailsHrefSchema, CaseDetailsLink, CasesNavigation } from '../links'; import * as i18n from './translations'; -import { Status } from '../status'; import { getSubCasesStatusCountsBadges, isSubCase } from './helpers'; import { ALERTS } from '../../common/translations'; import { getActions } from './actions'; import { UpdateCase } from '../../containers/use_get_cases'; import { useDeleteCases } from '../../containers/use_delete_cases'; import { ConfirmDeleteCaseModal } from '../confirm_delete_case'; +import { useKibana } from '../../common/lib/kibana'; +import { StatusContextMenu } from '../case_action_bar/status_context_menu'; export type CasesColumns = | EuiTableActionsColumnType @@ -62,6 +64,7 @@ export interface GetCasesColumn { isLoadingCases: string[]; refreshCases?: (a?: boolean) => void; showActions: boolean; + userCanCrud: boolean; } export const useCasesColumns = ({ caseDetailsNavigation, @@ -72,6 +75,7 @@ export const useCasesColumns = ({ isLoadingCases, refreshCases, showActions, + userCanCrud, }: GetCasesColumn): CasesColumns[] => { // Delete case const { @@ -113,9 +117,8 @@ export const useCasesColumns = ({ () => getActions({ deleteCaseOnClick: toggleDeleteModal, - dispatchUpdate: handleDispatchUpdate, }), - [toggleDeleteModal, handleDispatchUpdate] + [toggleDeleteModal] ); useEffect(() => { @@ -267,18 +270,6 @@ export const useCasesColumns = ({ return getEmptyTagValue(); }, }, - { - name: i18n.INCIDENT_MANAGEMENT_SYSTEM, - render: (theCase: Case) => { - if (theCase.externalService != null) { - return renderStringField( - `${theCase.externalService.connectorName}`, - `case-table-column-connector` - ); - } - return getEmptyTagValue(); - }, - }, { name: i18n.STATUS, render: (theCase: Case) => { @@ -286,7 +277,20 @@ export const useCasesColumns = ({ if (theCase.status == null || theCase.type === CaseType.collection) { return getEmptyTagValue(); } - return ; + return ( + 0} + onStatusChanged={(status) => + handleDispatchUpdate({ + updateKey: 'status', + updateValue: status, + caseId: theCase.id, + version: theCase.version, + }) + } + /> + ); } const badges = getSubCasesStatusCountsBadges(theCase.subCases); @@ -322,36 +326,48 @@ interface Props { theCase: Case; } +const IconWrapper = styled.span` + svg { + height: 20px !important; + position: relative; + top: 3px; + width: 20px !important; + } +`; export const ExternalServiceColumn: React.FC = ({ theCase }) => { - const handleRenderDataToPush = useCallback(() => { - const lastCaseUpdate = theCase.updatedAt != null ? new Date(theCase.updatedAt) : null; - const lastCasePush = - theCase.externalService?.pushedAt != null - ? new Date(theCase.externalService?.pushedAt) - : null; - const hasDataToPush = - lastCasePush === null || - (lastCasePush != null && - lastCaseUpdate != null && - lastCasePush.getTime() < lastCaseUpdate?.getTime()); - return ( -

- - {theCase.externalService?.externalTitle} - - {hasDataToPush - ? renderStringField(i18n.REQUIRES_UPDATE, `case-table-column-external-requiresUpdate`) - : renderStringField(i18n.UP_TO_DATE, `case-table-column-external-upToDate`)} -

- ); - }, [theCase]); - if (theCase.externalService !== null) { - return handleRenderDataToPush(); + const { triggersActionsUi } = useKibana().services; + + if (theCase.externalService == null) { + return renderStringField(i18n.NOT_PUSHED, `case-table-column-external-notPushed`); } - return renderStringField(i18n.NOT_PUSHED, `case-table-column-external-notPushed`); + + const lastCaseUpdate = theCase.updatedAt != null ? new Date(theCase.updatedAt) : null; + const lastCasePush = + theCase.externalService?.pushedAt != null ? new Date(theCase.externalService?.pushedAt) : null; + const hasDataToPush = + lastCasePush === null || + (lastCaseUpdate != null && lastCasePush.getTime() < lastCaseUpdate?.getTime()); + return ( +

+ + + + + {theCase.externalService?.externalTitle} + + {hasDataToPush + ? renderStringField(i18n.REQUIRES_UPDATE, `case-table-column-external-requiresUpdate`) + : renderStringField(i18n.UP_TO_DATE, `case-table-column-external-upToDate`)} +

+ ); }; diff --git a/x-pack/plugins/cases/public/components/all_cases/index.test.tsx b/x-pack/plugins/cases/public/components/all_cases/index.test.tsx index c3c0f0bf075dd..4c15550f3ce3c 100644 --- a/x-pack/plugins/cases/public/components/all_cases/index.test.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/index.test.tsx @@ -36,7 +36,24 @@ const useGetCasesStatusMock = useGetCasesStatus as jest.Mock; const useUpdateCasesMock = useUpdateCases as jest.Mock; const useGetActionLicenseMock = useGetActionLicense as jest.Mock; -jest.mock('../../common/lib/kibana'); +jest.mock('../../common/lib/kibana', () => { + const originalModule = jest.requireActual('../../common/lib/kibana'); + return { + ...originalModule, + useKibana: () => ({ + services: { + triggersActionsUi: { + actionTypeRegistry: { + get: jest.fn().mockReturnValue({ + actionTypeTitle: '.jira', + iconClass: 'logoSecurity', + }), + }, + }, + }, + }), + }; +}); describe('AllCasesGeneric', () => { const defaultAllCasesProps: AllCasesProps = { @@ -119,6 +136,7 @@ describe('AllCasesGeneric', () => { handleIsLoading: jest.fn(), isLoadingCases: [], showActions: true, + userCanCrud: true, }; beforeEach(() => { @@ -274,7 +292,7 @@ describe('AllCasesGeneric', () => { }); }); - it('should render correct actions for case (with type individual and filter status open)', async () => { + it('should render delete actions for case', async () => { useGetCasesMock.mockReturnValue({ ...defaultGetCases, filterOptions: { ...defaultGetCases.filterOptions, status: CaseStatuses.open }, @@ -284,18 +302,12 @@ describe('AllCasesGeneric', () => { ); - wrapper.find('[data-test-subj="euiCollapsedItemActionsButton"]').first().simulate('click'); await waitFor(() => { - expect(wrapper.find('[data-test-subj="action-open"]').exists()).toBeFalsy(); - expect( - wrapper.find('[data-test-subj="action-in-progress"]').first().props().disabled - ).toBeFalsy(); - expect(wrapper.find('[data-test-subj="action-close"]').first().props().disabled).toBeFalsy(); expect(wrapper.find('[data-test-subj="action-delete"]').first().props().disabled).toBeFalsy(); }); }); - it('should enable correct actions for sub cases', async () => { + it.skip('should enable correct actions for sub cases', async () => { useGetCasesMock.mockReturnValue({ ...defaultGetCases, data: { @@ -327,25 +339,9 @@ describe('AllCasesGeneric', () => { ); - wrapper - .find( - '[data-test-subj="sub-cases-table-my-case-with-subcases"] [data-test-subj="euiCollapsedItemActionsButton"]' - ) - .last() - .simulate('click'); - - await waitFor(() => { - expect(wrapper.find('[data-test-subj="action-open"]').first().props().disabled).toEqual(true); - expect( - wrapper.find('[data-test-subj="action-in-progress"]').first().props().disabled - ).toEqual(true); - expect(wrapper.find('[data-test-subj="action-close"]').first().props().disabled).toEqual( - true - ); - expect(wrapper.find('[data-test-subj="action-delete"]').first().props().disabled).toEqual( - false - ); - }); + expect(wrapper.find('[data-test-subj="action-delete"]').first().props().disabled).toEqual( + false + ); }); it('should not render case link when caseDetailsNavigation is not passed or actions on showActions=false', async () => { @@ -362,6 +358,7 @@ describe('AllCasesGeneric', () => { filterStatus: CaseStatuses.open, handleIsLoading: jest.fn(), showActions: false, + userCanCrud: true, }) ); await waitFor(() => { @@ -387,14 +384,17 @@ describe('AllCasesGeneric', () => { }); }); - it('closes case when row action icon clicked', async () => { + it('Updates status when status context menu is updated', async () => { const wrapper = mount( ); - wrapper.find('[data-test-subj="euiCollapsedItemActionsButton"]').first().simulate('click'); - wrapper.find('[data-test-subj="action-close"]').first().simulate('click'); + wrapper.find(`[data-test-subj="case-view-status-dropdown"] button`).first().simulate('click'); + wrapper + .find(`[data-test-subj="case-view-status-dropdown-closed"] button`) + .first() + .simulate('click'); await waitFor(() => { const firstCase = useGetCasesMockState.data.cases[0]; @@ -409,66 +409,6 @@ describe('AllCasesGeneric', () => { }); }); - it('opens case when row action icon clicked', async () => { - useGetCasesMock.mockReturnValue({ - ...defaultGetCases, - data: { - ...defaultGetCases.data, - cases: [ - { - ...defaultGetCases.data.cases[0], - status: CaseStatuses.closed, - }, - ], - }, - filterOptions: { ...defaultGetCases.filterOptions, status: CaseStatuses.closed }, - }); - - const wrapper = mount( - - - - ); - - wrapper.find('[data-test-subj="euiCollapsedItemActionsButton"]').first().simulate('click'); - wrapper.find('[data-test-subj="action-open"]').first().simulate('click'); - - await waitFor(() => { - const firstCase = useGetCasesMockState.data.cases[0]; - expect(dispatchUpdateCaseProperty.mock.calls[0][0]).toEqual( - expect.objectContaining({ - caseId: firstCase.id, - updateKey: 'status', - updateValue: CaseStatuses.open, - version: firstCase.version, - }) - ); - }); - }); - - it('put case in progress when row action icon clicked', async () => { - const wrapper = mount( - - - - ); - - wrapper.find('[data-test-subj="euiCollapsedItemActionsButton"]').first().simulate('click'); - wrapper.find('[data-test-subj="action-in-progress"]').first().simulate('click'); - - await waitFor(() => { - const firstCase = useGetCasesMockState.data.cases[0]; - expect(dispatchUpdateCaseProperty.mock.calls[0][0]).toEqual( - expect.objectContaining({ - caseId: firstCase.id, - updateKey: 'status', - updateValue: CaseStatuses['in-progress'], - version: firstCase.version, - }) - ); - }); - }); - it('Bulk delete', async () => { useGetCasesMock.mockReturnValue({ ...defaultGetCases, @@ -794,7 +734,7 @@ describe('AllCasesGeneric', () => { closedAt: null, closedBy: null, comments: [], - connector: { fields: null, id: 'none', name: 'My Connector', type: '.none' }, + connector: { fields: null, id: '123', name: 'My Connector', type: '.jira' }, createdAt: '2020-02-19T23:06:33.798Z', createdBy: { email: 'leslie.knope@elastic.co', diff --git a/x-pack/plugins/cases/public/components/all_cases/translations.ts b/x-pack/plugins/cases/public/components/all_cases/translations.ts index 8da90f32fabdf..be1aa256db657 100644 --- a/x-pack/plugins/cases/public/components/all_cases/translations.ts +++ b/x-pack/plugins/cases/public/components/all_cases/translations.ts @@ -90,10 +90,15 @@ export const REFRESH = i18n.translate('xpack.cases.caseTable.refreshTitle', { defaultMessage: 'Refresh', }); -export const SERVICENOW_LINK_ARIA = i18n.translate('xpack.cases.caseTable.serviceNowLinkAria', { - defaultMessage: 'click to view the incident on servicenow', -}); - +export const PUSH_LINK_ARIA = (thirdPartyName: string): string => + i18n.translate('xpack.cases.caseTable.pushLinkAria', { + values: { thirdPartyName }, + defaultMessage: 'click to view the incident on { thirdPartyName }.', + }); export const STATUS = i18n.translate('xpack.cases.caseTable.status', { defaultMessage: 'Status', }); + +export const CHANGE_STATUS = i18n.translate('xpack.cases.caseTable.changeStatus', { + defaultMessage: 'Change status', +}); diff --git a/x-pack/plugins/cases/public/components/case_action_bar/status_context_menu.tsx b/x-pack/plugins/cases/public/components/case_action_bar/status_context_menu.tsx index 3ee7ab6590215..603efb253f051 100644 --- a/x-pack/plugins/cases/public/components/case_action_bar/status_context_menu.tsx +++ b/x-pack/plugins/cases/public/components/case_action_bar/status_context_menu.tsx @@ -9,6 +9,7 @@ import React, { memo, useCallback, useMemo, useState } from 'react'; import { EuiPopover, EuiContextMenuPanel, EuiContextMenuItem } from '@elastic/eui'; import { caseStatuses, CaseStatuses } from '../../../common'; import { Status } from '../status'; +import { CHANGE_STATUS } from '../all_cases/translations'; interface Props { currentStatus: CaseStatuses; @@ -53,18 +54,17 @@ const StatusContextMenuComponent: React.FC = ({ ); return ( - <> - - - - + + + ); }; diff --git a/x-pack/plugins/cases/public/components/edit_connector/index.test.tsx b/x-pack/plugins/cases/public/components/edit_connector/index.test.tsx index 29d64afe3284f..fb45bf6ac3ae0 100644 --- a/x-pack/plugins/cases/public/components/edit_connector/index.test.tsx +++ b/x-pack/plugins/cases/public/components/edit_connector/index.test.tsx @@ -67,6 +67,7 @@ describe('EditConnector ', () => { ); + expect(wrapper.find(`[data-test-subj="has-data-to-push-button"]`).exists()).toBeTruthy(); wrapper.find('[data-test-subj="connector-edit"] button').simulate('click'); expect( @@ -173,6 +174,8 @@ describe('EditConnector ', () => { await waitFor(() => expect(wrapper.find(`[data-test-subj="connector-edit"]`).exists()).toBeFalsy() ); + + expect(wrapper.find(`[data-test-subj="has-data-to-push-button"]`).exists()).toBeFalsy(); }); it('displays the permissions error message when one is provided', async () => { @@ -191,6 +194,8 @@ describe('EditConnector ', () => { expect( wrapper.find(`[data-test-subj="edit-connector-no-connectors-msg"]`).exists() ).toBeFalsy(); + + expect(wrapper.find(`[data-test-subj="has-data-to-push-button"]`).exists()).toBeFalsy(); }); }); diff --git a/x-pack/plugins/cases/public/components/edit_connector/index.tsx b/x-pack/plugins/cases/public/components/edit_connector/index.tsx index fe92bd28ce21c..0a20d2f5c8303 100644 --- a/x-pack/plugins/cases/public/components/edit_connector/index.tsx +++ b/x-pack/plugins/cases/public/components/edit_connector/index.tsx @@ -330,11 +330,15 @@ export const EditConnector = React.memo( )} - {pushCallouts == null && !isLoading && !editConnector && ( - - {pushButton} - - )} + {pushCallouts == null && + !isLoading && + !editConnector && + userCanCrud && + !permissionsError && ( + + {pushButton} + + )} ); diff --git a/x-pack/plugins/cases/public/containers/mock.ts b/x-pack/plugins/cases/public/containers/mock.ts index df03311005bdb..a900010235c9f 100644 --- a/x-pack/plugins/cases/public/containers/mock.ts +++ b/x-pack/plugins/cases/public/containers/mock.ts @@ -176,6 +176,12 @@ export const basicPush = { export const pushedCase: Case = { ...basicCase, + connector: { + id: '123', + name: 'My Connector', + type: ConnectorTypes.jira, + fields: null, + }, externalService: basicPush, }; @@ -286,6 +292,12 @@ export const basicPushSnake = { export const pushedCaseSnake = { ...basicCaseSnake, + connector: { + id: '123', + name: 'My Connector', + type: ConnectorTypes.jira, + fields: null, + }, external_service: basicPushSnake, }; diff --git a/x-pack/plugins/cases/server/scripts/mock/case/post_case.json b/x-pack/plugins/cases/server/scripts/mock/case/post_case.json index bed342dd69fe9..a6e0e750a6683 100644 --- a/x-pack/plugins/cases/server/scripts/mock/case/post_case.json +++ b/x-pack/plugins/cases/server/scripts/mock/case/post_case.json @@ -12,5 +12,6 @@ }, "settings": { "syncAlerts": true - } + }, + "owner": "securitySolution" } diff --git a/x-pack/test/functional/apps/observability/feature_controls/observability_security.ts b/x-pack/test/functional/apps/observability/feature_controls/observability_security.ts index f2d78369bafee..90ccaf7c3df35 100644 --- a/x-pack/test/functional/apps/observability/feature_controls/observability_security.ts +++ b/x-pack/test/functional/apps/observability/feature_controls/observability_security.ts @@ -75,6 +75,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { }); it(`doesn't show read-only badge`, async () => { + await PageObjects.common.navigateToActualUrl('observabilityCases'); await PageObjects.observability.expectNoReadOnlyCallout(); }); @@ -142,6 +143,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { }); it(`shows read-only glasses badge`, async () => { + await PageObjects.common.navigateToActualUrl('observabilityCases'); await PageObjects.observability.expectReadOnlyGlassesBadge(); });