[SECURITY_SOLUTION][ENDPOINT] Add ability to view Trusted Apps from Ingest Integration Policy Edit page (#78854) (#79137)
* Refactor Callout shown in Ingest Edit Endpoint Integration Policy that display actions menu * Add `backComponent` to `<HeaderPage>` to allow for custom back buttons * Back button displayed on Trusted Apps List when route state is defined
This commit is contained in:
parent
e239807b66
commit
d0d80e0fbb
8 changed files with 325 additions and 62 deletions
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
import { TypeOf } from '@kbn/config-schema';
|
||||
import { ApplicationStart } from 'kibana/public';
|
||||
import {
|
||||
DeleteTrustedAppsRequestSchema,
|
||||
GetTrustedAppsRequestSchema,
|
||||
|
@ -65,3 +66,15 @@ export type TrustedApp = NewTrustedApp & {
|
|||
created_at: string;
|
||||
created_by: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Supported React-Router state for the Trusted Apps List page
|
||||
*/
|
||||
export interface TrustedAppsListPageRouteState {
|
||||
/** Where the user should be redirected to when the `Back` button is clicked */
|
||||
onBackButtonNavigateTo: Parameters<ApplicationStart['navigateToApp']>;
|
||||
/** The URL for the `Back` button */
|
||||
backButtonUrl?: string;
|
||||
/** The label for the button */
|
||||
backButtonLabel?: string;
|
||||
}
|
||||
|
|
|
@ -71,6 +71,8 @@ interface BackOptions {
|
|||
|
||||
export interface HeaderPageProps extends HeaderProps {
|
||||
backOptions?: BackOptions;
|
||||
/** A component to be displayed as the back button. Used only if `backOption` is not defined */
|
||||
backComponent?: React.ReactNode;
|
||||
badgeOptions?: BadgeOptions;
|
||||
children?: React.ReactNode;
|
||||
draggableArguments?: DraggableArguments;
|
||||
|
@ -83,6 +85,7 @@ export interface HeaderPageProps extends HeaderProps {
|
|||
|
||||
const HeaderPageComponent: React.FC<HeaderPageProps> = ({
|
||||
backOptions,
|
||||
backComponent,
|
||||
badgeOptions,
|
||||
border,
|
||||
children,
|
||||
|
@ -123,6 +126,8 @@ const HeaderPageComponent: React.FC<HeaderPageProps> = ({
|
|||
</LinkBack>
|
||||
)}
|
||||
|
||||
{!backOptions && backComponent && <>{backComponent}</>}
|
||||
|
||||
{titleNode || (
|
||||
<Title
|
||||
draggableArguments={draggableArguments}
|
||||
|
|
|
@ -27,10 +27,11 @@ interface AdministrationListPageProps {
|
|||
title: React.ReactNode;
|
||||
subtitle: React.ReactNode;
|
||||
actions?: React.ReactNode;
|
||||
headerBackComponent?: React.ReactNode;
|
||||
}
|
||||
|
||||
export const AdministrationListPage: FC<AdministrationListPageProps & CommonProps> = memo(
|
||||
({ beta, title, subtitle, actions, children, ...otherProps }) => {
|
||||
({ beta, title, subtitle, actions, children, headerBackComponent, ...otherProps }) => {
|
||||
const badgeOptions = !beta ? undefined : { beta: true, text: BETA_BADGE_LABEL };
|
||||
|
||||
return (
|
||||
|
@ -39,6 +40,7 @@ export const AdministrationListPage: FC<AdministrationListPageProps & CommonProp
|
|||
hideSourcerer={true}
|
||||
title={title}
|
||||
subtitle={subtitle}
|
||||
backComponent={headerBackComponent}
|
||||
badgeOptions={badgeOptions}
|
||||
>
|
||||
{actions}
|
||||
|
|
|
@ -4,17 +4,34 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React, { memo, useMemo } from 'react';
|
||||
import React, { memo, useCallback, useMemo, useState } from 'react';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { EuiCallOut, EuiText, EuiSpacer } from '@elastic/eui';
|
||||
import { LinkToApp } from '../../../../../common/components/endpoint/link_to_app';
|
||||
import {
|
||||
EuiCallOut,
|
||||
EuiText,
|
||||
EuiSpacer,
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiContextMenuPanel,
|
||||
EuiPopover,
|
||||
EuiButton,
|
||||
EuiContextMenuItem,
|
||||
EuiContextMenuPanelProps,
|
||||
} from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import {
|
||||
CustomConfigurePackagePolicyContent,
|
||||
CustomConfigurePackagePolicyProps,
|
||||
pagePathGetters,
|
||||
} from '../../../../../../../ingest_manager/public';
|
||||
import { getPolicyDetailPath } from '../../../../common/routing';
|
||||
import { getPolicyDetailPath, getTrustedAppsListPath } from '../../../../common/routing';
|
||||
import { MANAGEMENT_APP_ID } from '../../../../common/constants';
|
||||
import { PolicyDetailsRouteState } from '../../../../../../common/endpoint/types';
|
||||
import {
|
||||
PolicyDetailsRouteState,
|
||||
TrustedAppsListPageRouteState,
|
||||
} from '../../../../../../common/endpoint/types';
|
||||
import { useKibana } from '../../../../../common/lib/kibana';
|
||||
import { useNavigateToAppEventHandler } from '../../../../../common/hooks/endpoint/use_navigate_to_app_event_handler';
|
||||
|
||||
/**
|
||||
* Exports Endpoint-specific package policy instructions
|
||||
|
@ -26,27 +43,6 @@ export const ConfigureEndpointPackagePolicy = memo<CustomConfigurePackagePolicyC
|
|||
packagePolicyId,
|
||||
packagePolicy: { policy_id: agentPolicyId },
|
||||
}: CustomConfigurePackagePolicyProps) => {
|
||||
let policyUrl = '';
|
||||
if (from === 'edit' && packagePolicyId) {
|
||||
// Cannot use formalUrl here since the code is called in Ingest, which does not use redux
|
||||
policyUrl = getPolicyDetailPath(packagePolicyId);
|
||||
}
|
||||
|
||||
const policyDetailRouteState = useMemo((): undefined | PolicyDetailsRouteState => {
|
||||
if (from !== 'edit') {
|
||||
return undefined;
|
||||
}
|
||||
const navigateTo: PolicyDetailsRouteState['onSaveNavigateTo'] &
|
||||
PolicyDetailsRouteState['onCancelNavigateTo'] = [
|
||||
'ingestManager',
|
||||
{ path: `#/policies/${agentPolicyId}/edit-integration/${packagePolicyId}` },
|
||||
];
|
||||
return {
|
||||
onSaveNavigateTo: navigateTo,
|
||||
onCancelNavigateTo: navigateTo,
|
||||
};
|
||||
}, [agentPolicyId, from, packagePolicyId]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<EuiSpacer size="m" />
|
||||
|
@ -55,39 +51,149 @@ export const ConfigureEndpointPackagePolicy = memo<CustomConfigurePackagePolicyC
|
|||
iconType="iInCircle"
|
||||
>
|
||||
<EuiText size="s">
|
||||
<p>
|
||||
{from === 'edit' ? (
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpoint.ingestManager.editPackagePolicy.endpointConfiguration"
|
||||
defaultMessage="Click {advancedConfigOptionsLink} to edit advanced configuration options."
|
||||
values={{
|
||||
advancedConfigOptionsLink: (
|
||||
<LinkToApp
|
||||
data-test-subj="editLinkToPolicyDetails"
|
||||
appId={MANAGEMENT_APP_ID}
|
||||
appPath={policyUrl}
|
||||
appState={policyDetailRouteState}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpoint.ingestManager.editPackagePolicy.endpointConfigurationLink"
|
||||
defaultMessage="here"
|
||||
/>
|
||||
</LinkToApp>
|
||||
),
|
||||
}}
|
||||
{from === 'edit' ? (
|
||||
<>
|
||||
<EditFlowMessage
|
||||
agentPolicyId={agentPolicyId}
|
||||
integrationPolicyId={packagePolicyId!}
|
||||
/>
|
||||
) : (
|
||||
</>
|
||||
) : (
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpoint.ingestManager.createPackagePolicy.endpointConfiguration"
|
||||
defaultMessage="We'll save your integration with our recommended defaults. You can change this later by editing the Endpoint Security integration within your agent policy."
|
||||
/>
|
||||
)}
|
||||
</p>
|
||||
</p>
|
||||
)}
|
||||
</EuiText>
|
||||
</EuiCallOut>
|
||||
</>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
ConfigureEndpointPackagePolicy.displayName = 'ConfigureEndpointPackagePolicy';
|
||||
|
||||
const EditFlowMessage = memo<{
|
||||
agentPolicyId: string;
|
||||
integrationPolicyId: string;
|
||||
}>(({ agentPolicyId, integrationPolicyId }) => {
|
||||
const {
|
||||
services: {
|
||||
application: { getUrlForApp },
|
||||
},
|
||||
} = useKibana();
|
||||
|
||||
const [isMenuOpen, setIsMenuOpen] = useState<boolean>(false);
|
||||
|
||||
const navigateBackToIngest = useMemo<
|
||||
PolicyDetailsRouteState['onSaveNavigateTo'] &
|
||||
PolicyDetailsRouteState['onCancelNavigateTo'] &
|
||||
TrustedAppsListPageRouteState['onBackButtonNavigateTo']
|
||||
>(() => {
|
||||
return [
|
||||
'ingestManager',
|
||||
{
|
||||
path: `#${pagePathGetters.edit_integration({
|
||||
policyId: agentPolicyId,
|
||||
packagePolicyId: integrationPolicyId!,
|
||||
})}`,
|
||||
},
|
||||
];
|
||||
}, [agentPolicyId, integrationPolicyId]);
|
||||
|
||||
const handleClosePopup = useCallback(() => setIsMenuOpen(false), []);
|
||||
|
||||
const handleSecurityPolicyAction = useNavigateToAppEventHandler<PolicyDetailsRouteState>(
|
||||
MANAGEMENT_APP_ID,
|
||||
{
|
||||
path: getPolicyDetailPath(integrationPolicyId),
|
||||
state: {
|
||||
onSaveNavigateTo: navigateBackToIngest,
|
||||
onCancelNavigateTo: navigateBackToIngest,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
const handleTrustedAppsAction = useNavigateToAppEventHandler<TrustedAppsListPageRouteState>(
|
||||
MANAGEMENT_APP_ID,
|
||||
{
|
||||
path: getTrustedAppsListPath(),
|
||||
state: {
|
||||
backButtonUrl: navigateBackToIngest[1]?.path
|
||||
? `${getUrlForApp('ingestManager')}${navigateBackToIngest[1].path}`
|
||||
: undefined,
|
||||
onBackButtonNavigateTo: navigateBackToIngest,
|
||||
backButtonLabel: i18n.translate(
|
||||
'xpack.securitySolution.endpoint.ingestManager.editPackagePolicy.trustedAppsMessageReturnBackLabel',
|
||||
{ defaultMessage: 'Back to Edit Integration' }
|
||||
),
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
const menuButton = useMemo(() => {
|
||||
return (
|
||||
<EuiButton
|
||||
size="s"
|
||||
iconType="arrowDown"
|
||||
iconSide="right"
|
||||
onClick={() => setIsMenuOpen((prevState) => !prevState)}
|
||||
data-test-subj="endpointActions"
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpoint.ingestManager.editPackagePolicy.menuButton"
|
||||
defaultMessage="Actions"
|
||||
/>
|
||||
</EuiButton>
|
||||
);
|
||||
}, []);
|
||||
|
||||
const actionItems = useMemo<EuiContextMenuPanelProps['items']>(() => {
|
||||
return [
|
||||
<EuiContextMenuItem
|
||||
key="policyDetails"
|
||||
onClick={handleSecurityPolicyAction}
|
||||
data-test-subj="securityPolicy"
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpoint.ingestManager.editPackagePolicy.actionSecurityPolicy"
|
||||
defaultMessage="Edit Security Policy"
|
||||
/>
|
||||
</EuiContextMenuItem>,
|
||||
<EuiContextMenuItem
|
||||
key="trustedApps"
|
||||
onClick={handleTrustedAppsAction}
|
||||
data-test-subj="trustedAppsAction"
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpoint.ingestManager.editPackagePolicy.actionTrustedApps"
|
||||
defaultMessage="View Trusted Applications"
|
||||
/>
|
||||
</EuiContextMenuItem>,
|
||||
];
|
||||
}, [handleSecurityPolicyAction, handleTrustedAppsAction]);
|
||||
|
||||
return (
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem>
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.endpoint.ingestManager.editPackagePolicy.message"
|
||||
defaultMessage="More advanced configuration options can be found by selecting an action from the menu"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiPopover
|
||||
button={menuButton}
|
||||
isOpen={isMenuOpen}
|
||||
closePopover={handleClosePopup}
|
||||
anchorPosition="downRight"
|
||||
panelPaddingSize="s"
|
||||
>
|
||||
<EuiContextMenuPanel data-test-subj="endpointActionsMenuPanel" items={actionItems} />
|
||||
</EuiPopover>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
});
|
||||
EditFlowMessage.displayName = 'EditFlowMessage';
|
||||
|
|
|
@ -3,10 +3,11 @@
|
|||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
import React, { memo, useCallback } from 'react';
|
||||
import React, { memo, useCallback, useMemo } from 'react';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { EuiButton } from '@elastic/eui';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { EuiButton, EuiButtonEmpty } from '@elastic/eui';
|
||||
import { useHistory, useLocation } from 'react-router-dom';
|
||||
import styled from 'styled-components';
|
||||
import { AdministrationListPage } from '../../../components/administration_list_page';
|
||||
import { TrustedAppsList } from './trusted_apps_list';
|
||||
import { TrustedAppDeletionDialog } from './trusted_app_deletion_dialog';
|
||||
|
@ -15,9 +16,12 @@ import { CreateTrustedAppFlyout } from './components/create_trusted_app_flyout';
|
|||
import { getTrustedAppsListPath } from '../../../common/routing';
|
||||
import { useTrustedAppsSelector } from './hooks';
|
||||
import { getListCurrentShowValue, getListUrlSearchParams } from '../store/selectors';
|
||||
import { TrustedAppsListPageRouteState } from '../../../../../common/endpoint/types';
|
||||
import { useNavigateToAppEventHandler } from '../../../../common/hooks/endpoint/use_navigate_to_app_event_handler';
|
||||
|
||||
export const TrustedAppsPage = memo(() => {
|
||||
const history = useHistory();
|
||||
const { state: routeState } = useLocation<TrustedAppsListPageRouteState | undefined>();
|
||||
const urlParams = useTrustedAppsSelector(getListUrlSearchParams);
|
||||
const showAddFlout = useTrustedAppsSelector(getListCurrentShowValue) === 'create';
|
||||
const handleAddButtonClick = useCallback(() => {
|
||||
|
@ -33,6 +37,15 @@ export const TrustedAppsPage = memo(() => {
|
|||
history.push(getTrustedAppsListPath(paginationParamsOnly));
|
||||
}, [history, urlParams]);
|
||||
|
||||
const backButton = useMemo(() => {
|
||||
if (routeState && routeState.onBackButtonNavigateTo) {
|
||||
return <BackToExternalAppButton {...routeState} />;
|
||||
}
|
||||
return null;
|
||||
// FIXME: Route state is being deleted by some parent component
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
const addButton = (
|
||||
<EuiButton
|
||||
fill
|
||||
|
@ -50,6 +63,7 @@ export const TrustedAppsPage = memo(() => {
|
|||
|
||||
return (
|
||||
<AdministrationListPage
|
||||
data-test-subj="trustedAppsListPage"
|
||||
beta={true}
|
||||
title={
|
||||
<FormattedMessage
|
||||
|
@ -57,6 +71,7 @@ export const TrustedAppsPage = memo(() => {
|
|||
defaultMessage="Trusted Applications"
|
||||
/>
|
||||
}
|
||||
headerBackComponent={backButton}
|
||||
subtitle={
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.trustedapps.list.pageSubTitle"
|
||||
|
@ -80,3 +95,43 @@ export const TrustedAppsPage = memo(() => {
|
|||
});
|
||||
|
||||
TrustedAppsPage.displayName = 'TrustedAppsPage';
|
||||
|
||||
const EuiButtonEmptyStyled = styled(EuiButtonEmpty)`
|
||||
margin-bottom: ${({ theme }) => theme.eui.euiSizeS};
|
||||
|
||||
.euiIcon {
|
||||
width: ${({ theme }) => theme.eui.euiIconSizes.small};
|
||||
height: ${({ theme }) => theme.eui.euiIconSizes.small};
|
||||
}
|
||||
|
||||
.text {
|
||||
font-size: ${({ theme }) => theme.eui.euiFontSizeXS};
|
||||
}
|
||||
`;
|
||||
|
||||
const BackToExternalAppButton = memo<TrustedAppsListPageRouteState>(
|
||||
({ backButtonLabel, backButtonUrl, onBackButtonNavigateTo }) => {
|
||||
const handleBackOnClick = useNavigateToAppEventHandler(...onBackButtonNavigateTo!);
|
||||
|
||||
return (
|
||||
<EuiButtonEmptyStyled
|
||||
flush="left"
|
||||
size="xs"
|
||||
iconType="arrowLeft"
|
||||
href={backButtonUrl!}
|
||||
onClick={handleBackOnClick}
|
||||
textProps={{ className: 'text' }}
|
||||
data-test-subj="backToOrigin"
|
||||
>
|
||||
{backButtonLabel || (
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.trustedapps.list.backButton"
|
||||
defaultMessage="Back"
|
||||
/>
|
||||
)}
|
||||
</EuiButtonEmptyStyled>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
BackToExternalAppButton.displayName = 'BackToExternalAppButton';
|
||||
|
|
|
@ -16,6 +16,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
|||
'policy',
|
||||
'endpointPageUtils',
|
||||
'ingestManagerCreatePackagePolicy',
|
||||
'trustedApps',
|
||||
]);
|
||||
const testSubjects = getService('testSubjects');
|
||||
const policyTestResources = getService('policyTestResources');
|
||||
|
@ -250,6 +251,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when on Ingest Policy Edit Package Policy page', async () => {
|
||||
let policyInfo: PolicyTestResourceInfo;
|
||||
beforeEach(async () => {
|
||||
|
@ -265,16 +267,31 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
|||
await policyInfo.cleanup();
|
||||
}
|
||||
});
|
||||
it('should show a link to Policy Details', async () => {
|
||||
await testSubjects.existOrFail('editLinkToPolicyDetails');
|
||||
|
||||
it('should show callout', async () => {
|
||||
await testSubjects.existOrFail('endpointPackagePolicy_edit');
|
||||
});
|
||||
it('should navigate to Policy Details when the link is clicked', async () => {
|
||||
const linkToPolicy = await testSubjects.find('editLinkToPolicyDetails');
|
||||
await linkToPolicy.click();
|
||||
|
||||
it('should show actions button with expected action items', async () => {
|
||||
const actionsButton = await pageObjects.ingestManagerCreatePackagePolicy.findEndpointActionsButton();
|
||||
await actionsButton.click();
|
||||
const menuPanel = await testSubjects.find('endpointActionsMenuPanel');
|
||||
const actionItems = await menuPanel.findAllByTagName<'button'>('button');
|
||||
const expectedItems = ['Edit Security Policy', 'View Trusted Applications'];
|
||||
|
||||
for (const action of actionItems) {
|
||||
const buttonText = await action.getVisibleText();
|
||||
expect(buttonText).to.be(expectedItems.find((item) => item === buttonText));
|
||||
}
|
||||
});
|
||||
|
||||
it('should navigate to Policy Details when the edit security policy action is clicked', async () => {
|
||||
await pageObjects.ingestManagerCreatePackagePolicy.selectEndpointAction('policy');
|
||||
await pageObjects.policy.ensureIsOnDetailsPage();
|
||||
});
|
||||
|
||||
it('should allow the user to navigate, edit, save Policy Details and be redirected back to ingest', async () => {
|
||||
await (await testSubjects.find('editLinkToPolicyDetails')).click();
|
||||
await pageObjects.ingestManagerCreatePackagePolicy.selectEndpointAction('policy');
|
||||
await pageObjects.policy.ensureIsOnDetailsPage();
|
||||
await pageObjects.endpointPageUtils.clickOnEuiCheckbox('policyWindowsEvent_dns');
|
||||
await pageObjects.policy.confirmAndSave();
|
||||
|
@ -282,11 +299,24 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
|||
await testSubjects.existOrFail('policyDetailsSuccessMessage');
|
||||
await pageObjects.ingestManagerCreatePackagePolicy.ensureOnEditPageOrFail();
|
||||
});
|
||||
|
||||
it('should navigate back to Ingest Policy Edit package page on click of cancel button', async () => {
|
||||
await (await testSubjects.find('editLinkToPolicyDetails')).click();
|
||||
await pageObjects.ingestManagerCreatePackagePolicy.selectEndpointAction('policy');
|
||||
await (await pageObjects.policy.findCancelButton()).click();
|
||||
await pageObjects.ingestManagerCreatePackagePolicy.ensureOnEditPageOrFail();
|
||||
});
|
||||
|
||||
it('should navigate to Trusted Apps', async () => {
|
||||
await pageObjects.ingestManagerCreatePackagePolicy.selectEndpointAction('trustedApps');
|
||||
await pageObjects.trustedApps.ensureIsOnTrustedAppsListPage();
|
||||
});
|
||||
|
||||
it('should show the back button on Trusted Apps Page and navigate back to fleet', async () => {
|
||||
await pageObjects.ingestManagerCreatePackagePolicy.selectEndpointAction('trustedApps');
|
||||
const backButton = await pageObjects.trustedApps.findTrustedAppsListPageBackButton();
|
||||
await backButton.click();
|
||||
await pageObjects.ingestManagerCreatePackagePolicy.ensureOnEditPageOrFail();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
import { FtrProviderContext } from '../ftr_provider_context';
|
||||
import { WebElementWrapper } from '../../../../test/functional/services/lib/web_element_wrapper';
|
||||
|
||||
export function IngestManagerCreatePackagePolicy({
|
||||
getService,
|
||||
|
@ -13,6 +14,7 @@ export function IngestManagerCreatePackagePolicy({
|
|||
const testSubjects = getService('testSubjects');
|
||||
const find = getService('find');
|
||||
const pageObjects = getPageObjects(['common']);
|
||||
const browser = getService('browser');
|
||||
|
||||
return {
|
||||
/**
|
||||
|
@ -101,5 +103,38 @@ export function IngestManagerCreatePackagePolicy({
|
|||
});
|
||||
await this.ensureOnEditPageOrFail();
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the Endpoint Callout that is displayed on the Integration Policy create/edit pages
|
||||
*/
|
||||
async findEndpointActionsButton() {
|
||||
const button = await testSubjects.find('endpointActions');
|
||||
await this.scrollToCenterOfWindow(button);
|
||||
return button;
|
||||
},
|
||||
|
||||
/**
|
||||
* Center a given Element on the Window viewport
|
||||
* @param element
|
||||
*/
|
||||
async scrollToCenterOfWindow(element: WebElementWrapper) {
|
||||
const [elementPosition, windowSize] = await Promise.all([
|
||||
element.getPosition(),
|
||||
browser.getWindowSize(),
|
||||
]);
|
||||
await browser.execute(
|
||||
`document.scrollingElement.scrollTop = ${elementPosition.y - windowSize.height / 2}`
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Will click on the given Endpoint Action (from the Actions dropdown)
|
||||
* @param action
|
||||
*/
|
||||
async selectEndpointAction(action: 'policy' | 'trustedApps') {
|
||||
await (await this.findEndpointActionsButton()).click();
|
||||
const testSubjId = action === 'policy' ? 'securityPolicy' : 'trustedAppsAction';
|
||||
await (await testSubjects.find(testSubjId)).click();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -5,8 +5,9 @@
|
|||
*/
|
||||
import { FtrProviderContext } from '../ftr_provider_context';
|
||||
|
||||
export function TrustedAppsPageProvider({ getPageObjects }: FtrProviderContext) {
|
||||
export function TrustedAppsPageProvider({ getService, getPageObjects }: FtrProviderContext) {
|
||||
const pageObjects = getPageObjects(['common', 'header', 'endpointPageUtils']);
|
||||
const testSubjects = getService('testSubjects');
|
||||
|
||||
return {
|
||||
async navigateToTrustedAppsList(searchParams?: string) {
|
||||
|
@ -16,5 +17,21 @@ export function TrustedAppsPageProvider({ getPageObjects }: FtrProviderContext)
|
|||
);
|
||||
await pageObjects.header.waitUntilLoadingHasFinished();
|
||||
},
|
||||
|
||||
/**
|
||||
* ensures that the Policy Page is the currently display view
|
||||
*/
|
||||
async ensureIsOnTrustedAppsListPage() {
|
||||
await testSubjects.existOrFail('trustedAppsListPage');
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the Back button displayed on the Trusted Apps list page when page is loaded
|
||||
* with route state that triggers return button to be displayed
|
||||
*/
|
||||
async findTrustedAppsListPageBackButton() {
|
||||
await this.ensureIsOnTrustedAppsListPage();
|
||||
return testSubjects.find('backToOrigin');
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue