From d956117a5b9f23ad57abbf20326e580f693aeb93 Mon Sep 17 00:00:00 2001 From: Rodney Norris Date: Tue, 8 Oct 2024 14:14:06 +0000 Subject: [PATCH] test: introduce functional_search suite Adding the function_search suite with a test for the new search solution nav. But this suite will also be a place where we can test search functionality not tied to the enterprise_search node. --- .buildkite/ftr_platform_stateful_configs.yml | 1 + .github/CODEOWNERS | 1 + .../page_objects/solution_navigation.ts | 12 + x-pack/test/functional_search/config.ts | 31 ++ .../functional_search/ftr_provider_context.ts | 13 + x-pack/test/functional_search/index.ts | 15 + x-pack/test/functional_search/services.ts | 10 + .../tests/solution_navigation.ts | 314 ++++++++++++++++++ 8 files changed, 397 insertions(+) create mode 100644 x-pack/test/functional_search/config.ts create mode 100644 x-pack/test/functional_search/ftr_provider_context.ts create mode 100644 x-pack/test/functional_search/index.ts create mode 100644 x-pack/test/functional_search/services.ts create mode 100644 x-pack/test/functional_search/tests/solution_navigation.ts diff --git a/.buildkite/ftr_platform_stateful_configs.yml b/.buildkite/ftr_platform_stateful_configs.yml index bc564624f8a5e..d8a538f82779e 100644 --- a/.buildkite/ftr_platform_stateful_configs.yml +++ b/.buildkite/ftr_platform_stateful_configs.yml @@ -272,6 +272,7 @@ enabled: - x-pack/test/functional/config.upgrade_assistant.ts - x-pack/test/functional_cloud/config.ts - x-pack/test/functional_solution_sidenav/config.ts + - x-pack/test/functional_search/config.ts - x-pack/test/kubernetes_security/basic/config.ts - x-pack/test/licensing_plugin/config.public.ts - x-pack/test/licensing_plugin/config.ts diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index d4c8f52704e96..47911e49ee1a4 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1480,6 +1480,7 @@ x-pack/test/api_integration/apis/management/index_management/inference_endpoints /x-pack/test_serverless/api_integration/test_suites/search @elastic/search-kibana /x-pack/test_serverless/functional/page_objects/svl_api_keys.ts @elastic/search-kibana /x-pack/test_serverless/functional/page_objects/svl_search_* @elastic/search-kibana +/x-pack/test/functional_search/ @elastic/search-kibana # Management Experience - Deployment Management /x-pack/test_serverless/**/test_suites/common/index_management/ @elastic/kibana-management diff --git a/test/functional/page_objects/solution_navigation.ts b/test/functional/page_objects/solution_navigation.ts index a0544e1100507..79e13b0f24943 100644 --- a/test/functional/page_objects/solution_navigation.ts +++ b/test/functional/page_objects/solution_navigation.ts @@ -138,6 +138,18 @@ export function SolutionNavigationProvider(ctx: Pick; +export { pageObjects }; diff --git a/x-pack/test/functional_search/index.ts b/x-pack/test/functional_search/index.ts new file mode 100644 index 0000000000000..149b3dbcf7eca --- /dev/null +++ b/x-pack/test/functional_search/index.ts @@ -0,0 +1,15 @@ +/* + * 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. + */ +/* eslint-disable import/no-default-export */ + +import { FtrProviderContext } from './ftr_provider_context'; + +export default ({ loadTestFile }: FtrProviderContext): void => { + describe('Search solution tests', function () { + loadTestFile(require.resolve('./tests/solution_navigation')); + }); +}; diff --git a/x-pack/test/functional_search/services.ts b/x-pack/test/functional_search/services.ts new file mode 100644 index 0000000000000..9508ce5eba16d --- /dev/null +++ b/x-pack/test/functional_search/services.ts @@ -0,0 +1,10 @@ +/* + * 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 { services as functionalServices } from '../functional/services'; + +export const services = functionalServices; diff --git a/x-pack/test/functional_search/tests/solution_navigation.ts b/x-pack/test/functional_search/tests/solution_navigation.ts new file mode 100644 index 0000000000000..8a06ad1193372 --- /dev/null +++ b/x-pack/test/functional_search/tests/solution_navigation.ts @@ -0,0 +1,314 @@ +/* + * 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 { FtrProviderContext } from '../ftr_provider_context'; + +export default function searchSolutionNavigation({ + getPageObjects, + getService, +}: FtrProviderContext) { + const { common, solutionNavigation } = getPageObjects(['common', 'solutionNavigation']); + const spaces = getService('spaces'); + const browser = getService('browser'); + + describe('Search Solution Navigation', () => { + let cleanUp: () => Promise; + let spaceCreated: { id: string } = { id: '' }; + + before(async () => { + // Navigate to the spaces management page which will log us in Kibana + await common.navigateToUrl('management', 'kibana/spaces', { + shouldUseHashForSubUrl: false, + }); + + // Create a space with the search solution and navigate to its home page + ({ cleanUp, space: spaceCreated } = await spaces.create({ solution: 'es' })); + await browser.navigateTo(spaces.getRootUrl(spaceCreated.id)); + }); + + after(async () => { + // Clean up space created + await cleanUp(); + }); + + it('renders expected side nav items', async () => { + // Verify all expected top-level links exist + await solutionNavigation.sidenav.expectLinkExists({ text: 'Overview' }); + await solutionNavigation.sidenav.expectLinkExists({ text: 'Dev Tools' }); + await solutionNavigation.sidenav.expectLinkExists({ text: 'Discover' }); + await solutionNavigation.sidenav.expectLinkExists({ text: 'Dashboards' }); + await solutionNavigation.sidenav.expectLinkExists({ text: 'Indices' }); + await solutionNavigation.sidenav.expectLinkExists({ text: 'Connectors' }); + await solutionNavigation.sidenav.expectLinkExists({ text: 'Web crawlers' }); + await solutionNavigation.sidenav.expectLinkExists({ text: 'Playground' }); + await solutionNavigation.sidenav.expectLinkExists({ text: 'Search applications' }); + await solutionNavigation.sidenav.expectLinkExists({ text: 'Behavioral Analytics' }); + await solutionNavigation.sidenav.expectLinkExists({ text: 'App Search' }); + await solutionNavigation.sidenav.expectLinkExists({ text: 'Workplace Search' }); + await solutionNavigation.sidenav.expectLinkExists({ text: 'Other tools' }); + }); + + it('has expected navigation', async () => { + const expectNoPageReload = await solutionNavigation.createNoPageReloadCheck(); + + // check side nav links + await solutionNavigation.sidenav.expectSectionExists('search_project_nav'); + await solutionNavigation.sidenav.expectLinkActive({ + deepLinkId: 'enterpriseSearch', + }); + await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ + deepLinkId: 'enterpriseSearch', + }); + + // check Dev tools + await solutionNavigation.sidenav.clickLink({ + deepLinkId: 'dev_tools', + }); + await solutionNavigation.sidenav.expectLinkActive({ + deepLinkId: 'dev_tools', + }); + await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ text: 'Dev Tools' }); + await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ + deepLinkId: 'dev_tools', + }); + + // check Kibana + // > Discover + await solutionNavigation.sidenav.clickLink({ + deepLinkId: 'discover', + }); + await solutionNavigation.sidenav.expectLinkActive({ + deepLinkId: 'discover', + }); + await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ text: 'Kibana' }); + await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ text: 'Discover' }); + await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ + deepLinkId: 'discover', + }); + // > Dashboards + await solutionNavigation.sidenav.clickLink({ + deepLinkId: 'dashboards', + }); + await solutionNavigation.sidenav.expectLinkActive({ + deepLinkId: 'dashboards', + }); + await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ text: 'Kibana' }); + await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ text: 'Dashboards' }); + await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ + deepLinkId: 'dashboards', + }); + + // check the Content + // > Indices section + await solutionNavigation.sidenav.clickLink({ + deepLinkId: 'enterpriseSearchContent:searchIndices', + }); + await solutionNavigation.sidenav.expectLinkActive({ + deepLinkId: 'enterpriseSearchContent:searchIndices', + }); + await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ text: 'Content' }); + await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ text: 'Indices' }); + await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ + deepLinkId: 'enterpriseSearchContent:searchIndices', + }); + // > Connectors + await solutionNavigation.sidenav.clickLink({ + deepLinkId: 'enterpriseSearchContent:connectors', + }); + await solutionNavigation.sidenav.expectLinkActive({ + deepLinkId: 'enterpriseSearchContent:connectors', + }); + await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ text: 'Content' }); + await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ text: 'Connectors' }); + await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ + deepLinkId: 'enterpriseSearchContent:connectors', + }); + // > Web Crawlers + await solutionNavigation.sidenav.clickLink({ + deepLinkId: 'enterpriseSearchContent:webCrawlers', + }); + await solutionNavigation.sidenav.expectLinkActive({ + deepLinkId: 'enterpriseSearchContent:webCrawlers', + }); + await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ text: 'Content' }); + await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ text: 'Web crawlers' }); + await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ + deepLinkId: 'enterpriseSearchContent:webCrawlers', + }); + + // check Build + // > Playground + await solutionNavigation.sidenav.clickLink({ + deepLinkId: 'enterpriseSearchApplications:playground', + }); + await solutionNavigation.sidenav.expectLinkActive({ + deepLinkId: 'enterpriseSearchApplications:playground', + }); + await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ text: 'Build' }); + await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ text: 'Playground' }); + await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ + deepLinkId: 'enterpriseSearchApplications:playground', + }); + // > Search applications + await solutionNavigation.sidenav.clickLink({ + deepLinkId: 'enterpriseSearchApplications:searchApplications', + }); + await solutionNavigation.sidenav.expectLinkActive({ + deepLinkId: 'enterpriseSearchApplications:searchApplications', + }); + await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ text: 'Build' }); + await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ + text: 'Search applications', + }); + await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ + deepLinkId: 'enterpriseSearchApplications:searchApplications', + }); + // > Behavioral Analytics + await solutionNavigation.sidenav.clickLink({ + deepLinkId: 'enterpriseSearchAnalytics', + }); + await solutionNavigation.sidenav.expectLinkActive({ + deepLinkId: 'enterpriseSearchAnalytics', + }); + await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ text: 'Build' }); + await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ + text: 'Behavioral Analytics', + }); + await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ + deepLinkId: 'enterpriseSearchAnalytics', + }); + + // check Relevance + // > Inference Endpoints + // TODO: FTRs don't have enterprise license, so inference endpoints not shown + // await solutionNavigation.sidenav.clickLink({ + // deepLinkId: 'enterpriseSearchRelevance:inferenceEndpoints', + // }); + // await solutionNavigation.sidenav.expectLinkActive({ + // deepLinkId: 'enterpriseSearchRelevance:inferenceEndpoints', + // }); + // await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ text: 'Relevance' }); + // await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ + // text: 'Inference Endpoints', + // }); + // await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ + // deepLinkId: 'enterpriseSearchRelevance:inferenceEndpoints', + // }); + + // check Enterprise Search + // > App Search + await solutionNavigation.sidenav.clickLink({ + deepLinkId: 'appSearch:engines', + }); + await solutionNavigation.sidenav.expectLinkActive({ + deepLinkId: 'appSearch:engines', + }); + // ent-search node not running for FTRs, so we see setup guide without breadcrumbs + // await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ + // text: 'App Search', + // }); + await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ + deepLinkId: 'appSearch:engines', + }); + // > Workplace Search + await solutionNavigation.sidenav.clickLink({ + deepLinkId: 'workplaceSearch', + }); + await solutionNavigation.sidenav.expectLinkActive({ + deepLinkId: 'workplaceSearch', + }); + // ent-search node not running for FTRs, so we see setup guide without breadcrumbs + // await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ + // text: 'Workplace Search', + // }); + await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ + deepLinkId: 'workplaceSearch', + }); + + // Other tools + await solutionNavigation.sidenav.openSection('search_project_nav.otherTools'); + // > Maps + await solutionNavigation.sidenav.clickLink({ + deepLinkId: 'maps', + }); + await solutionNavigation.sidenav.expectLinkActive({ + deepLinkId: 'maps', + }); + await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ text: 'Other tools' }); + await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ + text: 'Maps', + }); + await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ + deepLinkId: 'maps', + }); + // > Canvas + await solutionNavigation.sidenav.clickLink({ + deepLinkId: 'canvas', + }); + await solutionNavigation.sidenav.expectLinkActive({ + deepLinkId: 'canvas', + }); + await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ text: 'Other tools' }); + await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ + text: 'Canvas', + }); + await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ + deepLinkId: 'canvas', + }); + // > Graph + await solutionNavigation.sidenav.clickLink({ + deepLinkId: 'graph', + }); + await solutionNavigation.sidenav.expectLinkActive({ + deepLinkId: 'graph', + }); + await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ text: 'Other tools' }); + await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ + text: 'Graph', + }); + await solutionNavigation.breadcrumbs.expectBreadcrumbExists({ + deepLinkId: 'graph', + }); + await solutionNavigation.sidenav.closeSection('search_project_nav.otherTools'); + + await expectNoPageReload(); + }); + + it('renders only expected items', async () => { + await solutionNavigation.sidenav.openSection('search_project_nav.otherTools'); + await solutionNavigation.sidenav.openSection('project_settings_project_nav'); + await solutionNavigation.sidenav.expectOnlyDefinedLinks([ + 'search_project_nav', + 'enterpriseSearch', + 'dev_tools', + 'kibana', + 'discover', + 'dashboards', + 'content', + 'enterpriseSearchContent:searchIndices', + 'enterpriseSearchContent:connectors', + 'enterpriseSearchContent:webCrawlers', + 'build', + 'enterpriseSearchApplications:playground', + 'enterpriseSearchApplications:searchApplications', + 'enterpriseSearchAnalytics', + // 'relevance', + // 'enterpriseSearchRelevance:inferenceEndpoints', + 'entsearch', + 'appSearch:engines', + 'workplaceSearch', + 'otherTools', + 'maps', + 'canvas', + 'graph', + 'project_settings_project_nav', + 'ml:modelManagement', + 'stack_management', + ]); + }); + }); +}