diff --git a/test/functional/page_objects/common_page.ts b/test/functional/page_objects/common_page.ts index 9629b8ccf28e1..75a15cc16db2e 100644 --- a/test/functional/page_objects/common_page.ts +++ b/test/functional/page_objects/common_page.ts @@ -39,6 +39,14 @@ export function CommonPageProvider({ getService, getPageObjects }: FtrProviderCo const defaultTryTimeout = config.get('timeouts.try'); const defaultFindTimeout = config.get('timeouts.find'); + interface NavigateProps { + appConfig: {}; + ensureCurrentUrl: boolean; + shouldLoginIfPrompted: boolean; + shouldAcceptAlert: boolean; + useActualUrl: boolean; + } + class CommonPage { /** * Navigates the browser window to provided URL @@ -115,6 +123,34 @@ export function CommonPageProvider({ getService, getPageObjects }: FtrProviderCo return currentUrl; } + private async navigate(navigateProps: NavigateProps) { + const { + appConfig, + ensureCurrentUrl, + shouldLoginIfPrompted, + shouldAcceptAlert, + useActualUrl, + } = navigateProps; + const appUrl = getUrl.noAuth(config.get('servers.kibana'), appConfig); + + await retry.try(async () => { + if (useActualUrl) { + log.debug(`navigateToActualUrl ${appUrl}`); + await browser.get(appUrl); + } else { + await CommonPage.navigateToUrlAndHandleAlert(appUrl, shouldAcceptAlert); + } + + const currentUrl = shouldLoginIfPrompted + ? await this.loginIfPrompted(appUrl) + : await browser.getCurrentUrl(); + + if (ensureCurrentUrl && !currentUrl.includes(appUrl)) { + throw new Error(`expected ${currentUrl}.includes(${appUrl})`); + } + }); + } + /** * Navigates browser using the pathname from the appConfig and subUrl as the hash * @param appName As defined in the apps config, e.g. 'home' @@ -137,23 +173,44 @@ export function CommonPageProvider({ getService, getPageObjects }: FtrProviderCo hash: useActualUrl ? subUrl : `/${appName}/${subUrl}`, }; - const appUrl = getUrl.noAuth(config.get('servers.kibana'), appConfig); - - await retry.try(async () => { - if (useActualUrl) { - log.debug(`navigateToActualUrl ${appUrl}`); - await browser.get(appUrl); - } else { - await CommonPage.navigateToUrlAndHandleAlert(appUrl, shouldAcceptAlert); - } + await this.navigate({ + appConfig, + ensureCurrentUrl, + shouldLoginIfPrompted, + shouldAcceptAlert, + useActualUrl, + }); + } - const currentUrl = shouldLoginIfPrompted - ? await this.loginIfPrompted(appUrl) - : await browser.getCurrentUrl(); + /** + * Navigates browser using the pathname from the appConfig and subUrl as the extended path. + * This was added to be able to test an application that uses browser history over hash history. + * @param appName As defined in the apps config, e.g. 'home' + * @param subUrl The route after the appUrl, e.g. 'tutorial_directory/sampleData' + * @param args additional arguments + */ + public async navigateToUrlWithBrowserHistory( + appName: string, + subUrl?: string, + { + basePath = '', + ensureCurrentUrl = true, + shouldLoginIfPrompted = true, + shouldAcceptAlert = true, + useActualUrl = true, + } = {} + ) { + const appConfig = { + // subUrl following the basePath, assumes no hashes. Ex: 'app/endpoint/management' + pathname: `${basePath}${config.get(['apps', appName]).pathname}${subUrl}`, + }; - if (ensureCurrentUrl && !currentUrl.includes(appUrl)) { - throw new Error(`expected ${currentUrl}.includes(${appUrl})`); - } + await this.navigate({ + appConfig, + ensureCurrentUrl, + shouldLoginIfPrompted, + shouldAcceptAlert, + useActualUrl, }); } diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/index.tsx b/x-pack/plugins/endpoint/public/applications/endpoint/index.tsx index 1af27f039aca7..82c95b37ee7b0 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/index.tsx +++ b/x-pack/plugins/endpoint/public/applications/endpoint/index.tsx @@ -8,24 +8,55 @@ import * as React from 'react'; import ReactDOM from 'react-dom'; import { CoreStart, AppMountParameters } from 'kibana/public'; import { I18nProvider, FormattedMessage } from '@kbn/i18n/react'; +import { Route, BrowserRouter, Switch } from 'react-router-dom'; /** * This module will be loaded asynchronously to reduce the bundle size of your plugin's main bundle. */ -export function renderApp(coreStart: CoreStart, { element }: AppMountParameters) { +export function renderApp(coreStart: CoreStart, { appBasePath, element }: AppMountParameters) { coreStart.http.get('/api/endpoint/hello-world'); - ReactDOM.render(, element); + ReactDOM.render(, element); return () => { ReactDOM.unmountComponentAtNode(element); }; } -const AppRoot = React.memo(() => ( +interface RouterProps { + basename: string; +} + +const AppRoot: React.FunctionComponent = React.memo(({ basename }) => ( -

- -

+ + + ( +

+ +

+ )} + /> + ( +

+ +

+ )} + /> + ( + + )} + /> +
+
)); diff --git a/x-pack/test/functional/apps/endpoint/feature_controls/endpoint_spaces.ts b/x-pack/test/functional/apps/endpoint/feature_controls/endpoint_spaces.ts index 6b3b423e293c2..1d1fb566eb075 100644 --- a/x-pack/test/functional/apps/endpoint/feature_controls/endpoint_spaces.ts +++ b/x-pack/test/functional/apps/endpoint/feature_controls/endpoint_spaces.ts @@ -42,6 +42,15 @@ export default function({ getPageObjects, getService }: FtrProviderContext) { }); await testSubjects.existOrFail('welcomeTitle'); }); + + it(`endpoint management shows 'Manage Endpoints'`, async () => { + await pageObjects.common.navigateToUrlWithBrowserHistory('endpoint', '/management', { + basePath: '/s/custom_space', + ensureCurrentUrl: false, + shouldLoginIfPrompted: false, + }); + await testSubjects.existOrFail('endpointManagement'); + }); }); describe('space with endpoint disabled', () => {