From f7d1dd4bf35648b7a3db8fc7d16666f93949b43c Mon Sep 17 00:00:00 2001 From: Rodney Norris Date: Mon, 30 Sep 2024 12:49:59 -0500 Subject: [PATCH] [Search][Onboarding] Start Page File Upload & O11y links (#194231) ## Summary - Clean-up for start page - enabled submitting create index form w/ enter in index name input - extracted start page example to hook to make it easier to update later - Moved start page language up so changes are saved when switching between UI & Code views - Added File Upload link to the ML file uploader - Added callouts for O11y ### Screenshots image ### Checklist - [x] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [x] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed --------- Co-authored-by: Michael DeFazio --- .../search_indices/common/doc_links.ts | 2 + .../public/analytics/constants.ts | 1 + .../public/code_examples/create_index.ts | 2 + .../public/components/start/create_index.tsx | 197 ++++++++----- .../components/start/create_index_code.tsx | 32 +-- .../components/start/elasticsearch_start.tsx | 260 ++++++++++++------ .../start/hooks/use_coding_examples.tsx | 15 + .../public/components/start/types.ts | 3 + .../plugins/search_indices/public/plugin.ts | 3 + x-pack/plugins/search_indices/public/types.ts | 1 + .../svl_search_elasticsearch_start_page.ts | 23 ++ .../search/config.feature_flags.ts | 9 +- .../functional/test_suites/search/config.ts | 6 +- .../test_suites/search/elasticsearch_start.ts | 12 + 14 files changed, 389 insertions(+), 177 deletions(-) create mode 100644 x-pack/plugins/search_indices/public/components/start/hooks/use_coding_examples.tsx diff --git a/x-pack/plugins/search_indices/common/doc_links.ts b/x-pack/plugins/search_indices/common/doc_links.ts index 8cceb45041ab9..d7e7119dd7004 100644 --- a/x-pack/plugins/search_indices/common/doc_links.ts +++ b/x-pack/plugins/search_indices/common/doc_links.ts @@ -10,12 +10,14 @@ import { DocLinks } from '@kbn/doc-links'; class SearchIndicesDocLinks { public apiReference: string = ''; public setupSemanticSearch: string = ''; + public analyzeLogs: string = ''; constructor() {} setDocLinks(newDocLinks: DocLinks) { this.apiReference = newDocLinks.apiReference; this.setupSemanticSearch = newDocLinks.enterpriseSearch.semanticSearch; + this.analyzeLogs = newDocLinks.serverlessSearch.integrations; } } export const docLinks = new SearchIndicesDocLinks(); diff --git a/x-pack/plugins/search_indices/public/analytics/constants.ts b/x-pack/plugins/search_indices/public/analytics/constants.ts index 563e5b62382c0..2a8c6d0d0ea0d 100644 --- a/x-pack/plugins/search_indices/public/analytics/constants.ts +++ b/x-pack/plugins/search_indices/public/analytics/constants.ts @@ -13,6 +13,7 @@ export enum AnalyticsEvents { startCreateIndexLanguageSelect = 'start_code_lang_select', startCreateIndexCodeCopyInstall = 'start_code_copy_install', startCreateIndexCodeCopy = 'start_code_copy', + startFileUploadClick = 'start_file_upload', indexDetailsInstallCodeCopy = 'index_details_code_copy_install', indexDetailsAddMappingsCodeCopy = 'index_details_add_mappings_code_copy', indexDetailsIngestDocumentsCodeCopy = 'index_details_ingest_documents_code_copy', diff --git a/x-pack/plugins/search_indices/public/code_examples/create_index.ts b/x-pack/plugins/search_indices/public/code_examples/create_index.ts index 627329b37d0be..01d969df3d70d 100644 --- a/x-pack/plugins/search_indices/public/code_examples/create_index.ts +++ b/x-pack/plugins/search_indices/public/code_examples/create_index.ts @@ -13,6 +13,7 @@ import { PythonServerlessCreateIndexExamples } from './python'; import { ConsoleCreateIndexExamples } from './sense'; export const DefaultServerlessCodeExamples: CreateIndexCodeExamples = { + exampleType: 'search', sense: ConsoleCreateIndexExamples.default, curl: CurlCreateIndexExamples.default, python: PythonServerlessCreateIndexExamples.default, @@ -20,6 +21,7 @@ export const DefaultServerlessCodeExamples: CreateIndexCodeExamples = { }; export const DenseVectorSeverlessCodeExamples: CreateIndexCodeExamples = { + exampleType: 'vector', sense: ConsoleCreateIndexExamples.dense_vector, curl: CurlCreateIndexExamples.dense_vector, python: PythonServerlessCreateIndexExamples.dense_vector, diff --git a/x-pack/plugins/search_indices/public/components/start/create_index.tsx b/x-pack/plugins/search_indices/public/components/start/create_index.tsx index ae191481e5da4..bd80922d79689 100644 --- a/x-pack/plugins/search_indices/public/components/start/create_index.tsx +++ b/x-pack/plugins/search_indices/public/components/start/create_index.tsx @@ -13,12 +13,16 @@ import { EuiFlexItem, EuiForm, EuiFormRow, + EuiHorizontalRule, EuiIcon, + EuiLink, + EuiPanel, EuiSpacer, EuiText, EuiToolTip, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; import type { UserStartPrivilegesResponse } from '../../../common'; import { AnalyticsEvents } from '../../analytics/constants'; @@ -28,6 +32,7 @@ import { isValidIndexName } from '../../utils/indices'; import { useCreateIndex } from './hooks/use_create_index'; import { CreateIndexFormState } from './types'; +import { useKibana } from '../../hooks/use_kibana'; const CREATE_INDEX_CONTENT = i18n.translate( 'xpack.searchIndices.startPage.createIndex.action.text', @@ -47,6 +52,7 @@ export const CreateIndexForm = ({ formState, setFormState, }: CreateIndexFormProps) => { + const { application } = useKibana().services; const [indexNameHasError, setIndexNameHasError] = useState(false); const usageTracker = useUsageTracker(); const { createIndex, isLoading } = useCreateIndex(); @@ -65,93 +71,136 @@ export const CreateIndexForm = ({ setIndexNameHasError(invalidIndexName); } }; + const onFileUpload = useCallback(() => { + usageTracker.click(AnalyticsEvents.startFileUploadClick); + application.navigateToApp('ml', { path: 'filedatavisualizer' }); + }, [usageTracker, application]); return ( - - - + + - - - - - {userPrivileges?.privileges?.canCreateIndex === false ? ( - - {i18n.translate('xpack.searchIndices.startPage.createIndex.permissionTooltip', { - defaultMessage: 'You do not have permission to create an index.', - })} -

+ > + + )} + /> +
+ + + + {userPrivileges?.privileges?.canCreateIndex === false ? ( + + {i18n.translate('xpack.searchIndices.startPage.createIndex.permissionTooltip', { + defaultMessage: 'You do not have permission to create an index.', + })} +

+ } + > + + {CREATE_INDEX_CONTENT} + +
+ ) : ( {CREATE_INDEX_CONTENT} - - ) : ( - - {CREATE_INDEX_CONTENT} - - )} -
- - {userPrivileges?.privileges?.canCreateApiKeys && ( - - - -

- {i18n.translate( - 'xpack.searchIndices.startPage.createIndex.apiKeyCreation.description', - { - defaultMessage: "We'll create an API key for this index", - } - )} -

-
-
- )} -
-
-
+ )} + + + {userPrivileges?.privileges?.canCreateApiKeys && ( + + + +

+ {i18n.translate( + 'xpack.searchIndices.startPage.createIndex.apiKeyCreation.description', + { + defaultMessage: "We'll create an API key for this index", + } + )} +

+
+
+ )} +
+ + + + + + + + + + +

+ + {i18n.translate( + 'xpack.searchIndices.startPage.createIndex.fileUpload.link', + { + defaultMessage: 'Upload a file', + } + )} + + ), + }} + /> +

+
+
+
+
+ ); }; diff --git a/x-pack/plugins/search_indices/public/components/start/create_index_code.tsx b/x-pack/plugins/search_indices/public/components/start/create_index_code.tsx index 6fc2fb3b50e2f..e8efe1c3b7e66 100644 --- a/x-pack/plugins/search_indices/public/components/start/create_index_code.tsx +++ b/x-pack/plugins/search_indices/public/components/start/create_index_code.tsx @@ -4,46 +4,47 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import React, { useCallback, useMemo, useState } from 'react'; +import React, { useCallback, useMemo } from 'react'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { TryInConsoleButton } from '@kbn/try-in-console'; import { AnalyticsEvents } from '../../analytics/constants'; import { Languages, AvailableLanguages, LanguageOptions } from '../../code_examples'; -import { DenseVectorSeverlessCodeExamples } from '../../code_examples/create_index'; + import { useUsageTracker } from '../../hooks/use_usage_tracker'; import { useKibana } from '../../hooks/use_kibana'; import { useElasticsearchUrl } from '../../hooks/use_elasticsearch_url'; -import { getDefaultCodingLanguage } from '../../utils/language'; import { CodeSample } from '../shared/code_sample'; import { LanguageSelector } from '../shared/language_selector'; import { CreateIndexFormState } from './types'; +import { useStartPageCodingExamples } from './hooks/use_coding_examples'; export interface CreateIndexCodeViewProps { createIndexForm: CreateIndexFormState; + changeCodingLanguage: (language: AvailableLanguages) => void; } -// TODO: this will be dynamic based on stack / es3 & onboarding token -const SelectedCodeExamples = DenseVectorSeverlessCodeExamples; - -export const CreateIndexCodeView = ({ createIndexForm }: CreateIndexCodeViewProps) => { +export const CreateIndexCodeView = ({ + createIndexForm, + changeCodingLanguage, +}: CreateIndexCodeViewProps) => { const { application, share, console: consolePlugin } = useKibana().services; const usageTracker = useUsageTracker(); + const selectedCodeExamples = useStartPageCodingExamples(); - const [selectedLanguage, setSelectedLanguage] = - useState(getDefaultCodingLanguage); + const { codingLanguage: selectedLanguage } = createIndexForm; const onSelectLanguage = useCallback( (value: AvailableLanguages) => { - setSelectedLanguage(value); + changeCodingLanguage(value); usageTracker.count([ AnalyticsEvents.startCreateIndexLanguageSelect, `${AnalyticsEvents.startCreateIndexLanguageSelect}_${value}`, ]); }, - [usageTracker] + [usageTracker, changeCodingLanguage] ); const elasticsearchUrl = useElasticsearchUrl(); const codeParams = useMemo(() => { @@ -53,8 +54,8 @@ export const CreateIndexCodeView = ({ createIndexForm }: CreateIndexCodeViewProp }; }, [createIndexForm.indexName, elasticsearchUrl]); const selectedCodeExample = useMemo(() => { - return SelectedCodeExamples[selectedLanguage]; - }, [selectedLanguage]); + return selectedCodeExamples[selectedLanguage]; + }, [selectedLanguage, selectedCodeExamples]); return ( @@ -69,7 +70,7 @@ export const CreateIndexCodeView = ({ createIndexForm }: CreateIndexCodeViewProp {selectedLanguage === 'curl' && ( diff --git a/x-pack/plugins/search_indices/public/components/start/elasticsearch_start.tsx b/x-pack/plugins/search_indices/public/components/start/elasticsearch_start.tsx index 131948d1a0377..8d6e85bfc900a 100644 --- a/x-pack/plugins/search_indices/public/components/start/elasticsearch_start.tsx +++ b/x-pack/plugins/search_indices/public/components/start/elasticsearch_start.tsx @@ -5,33 +5,39 @@ * 2.0. */ -import React, { useCallback, useEffect, useState } from 'react'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { + EuiButtonEmpty, EuiButtonGroup, EuiFlexGroup, EuiFlexItem, - EuiForm, EuiIcon, EuiPanel, EuiSpacer, EuiText, + EuiTextAlign, EuiTitle, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import type { IndicesStatusResponse, UserStartPrivilegesResponse } from '../../../common'; +import { docLinks } from '../../../common/doc_links'; import { AnalyticsEvents } from '../../analytics/constants'; +import { AvailableLanguages } from '../../code_examples'; import { useUsageTracker } from '../../hooks/use_usage_tracker'; - import { generateRandomIndexName } from '../../utils/indices'; +import { getDefaultCodingLanguage } from '../../utils/language'; + import { CreateIndexForm } from './create_index'; import { CreateIndexCodeView } from './create_index_code'; import { CreateIndexFormState } from './types'; +import { useKibana } from '../../hooks/use_kibana'; function initCreateIndexState(): CreateIndexFormState { return { indexName: generateRandomIndexName(), + codingLanguage: getDefaultCodingLanguage(), }; } @@ -47,11 +53,13 @@ export interface ElasticsearchStartProps { } export const ElasticsearchStart = ({ userPrivileges }: ElasticsearchStartProps) => { + const { cloud, http } = useKibana().services; const [createIndexView, setCreateIndexView] = useState( userPrivileges?.privileges.canCreateIndex === false ? CreateIndexView.Code : CreateIndexView.UI ); - const [formState, setFormState] = useState(initCreateIndexState()); + const [formState, setFormState] = useState(initCreateIndexState); const usageTracker = useUsageTracker(); + useEffect(() => { usageTracker.load(AnalyticsEvents.startPageOpened); }, [usageTracker]); @@ -61,6 +69,15 @@ export const ElasticsearchStart = ({ userPrivileges }: ElasticsearchStartProps) setCreateIndexView(CreateIndexView.Code); } }, [userPrivileges]); + + const o11yTrialLink = useMemo(() => { + if (cloud && cloud.isServerlessEnabled) { + const baseUrl = cloud?.projectsUrl ?? 'https://cloud.elastic.co/projects/'; + return `${baseUrl}create/observability/start`; + } + return http.basePath.prepend('/app/observability/onboarding'); + }, [cloud, http]); + const onChangeView = useCallback( (id) => { switch (id) { @@ -76,6 +93,15 @@ export const ElasticsearchStart = ({ userPrivileges }: ElasticsearchStartProps) }, [usageTracker] ); + const onChangeCodingLanguage = useCallback( + (language: AvailableLanguages) => { + setFormState({ + ...formState, + codingLanguage: language, + }); + }, + [formState, setFormState] + ); return ( - - - - - - + + + + + +

{i18n.translate('xpack.searchIndices.startPage.pageTitle', { @@ -98,81 +124,153 @@ export const ElasticsearchStart = ({ userPrivileges }: ElasticsearchStartProps) })}

- - -

- {i18n.translate('xpack.searchIndices.startPage.pageDescription', { - defaultMessage: 'Vectorize, search, and visualize your data', - })} -

-
-
-
-
+
+
+ + +

+ {i18n.translate('xpack.searchIndices.startPage.pageDescription', { + defaultMessage: 'Vectorize, search, and visualize your data', + })} +

+
+ - - - - - -

- {i18n.translate('xpack.searchIndices.startPage.createIndex.title', { - defaultMessage: 'Create your first index', - })} -

-
-
- - - -
- -

- {i18n.translate('xpack.searchIndices.startPage.createIndex.description', { - defaultMessage: - 'An index stores your data and defines the schema, or field mappings, for your searches', - })} -

-
- {createIndexView === CreateIndexView.UI && ( - + + + +

+ {i18n.translate('xpack.searchIndices.startPage.createIndex.title', { + defaultMessage: 'Create your first index', + })} +

+
+
+ + - )} - {createIndexView === CreateIndexView.Code && ( - - )} +
-
+ +

+ {i18n.translate('xpack.searchIndices.startPage.createIndex.description', { + defaultMessage: + 'An index stores your data and defines the schema, or field mappings, for your searches', + })} +

+
+ {createIndexView === CreateIndexView.UI && ( + + )} + {createIndexView === CreateIndexView.Code && ( + + )} + +
+ + + + +
+ {i18n.translate('xpack.searchIndices.startPage.observabilityCallout.title', { + defaultMessage: 'Looking to store your logs or metrics data?', + })} +
+
+
+ + + + + {i18n.translate('xpack.searchIndices.startPage.observabilityCallout.logs.button', { + defaultMessage: 'Collect and analyze logs', + })} + + + + {i18n.translate( + 'xpack.searchIndices.startPage.observabilityCallout.logs.subTitle', + { + defaultMessage: 'Explore Logstash and Beats', + } + )} + + + + + or + + + + {i18n.translate( + 'xpack.searchIndices.startPage.observabilityCallout.o11yTrial.button', + { + defaultMessage: 'Start an Observability trial', + } + )} + + + + {i18n.translate( + 'xpack.searchIndices.startPage.observabilityCallout.o11yTrial.subTitle', + { + defaultMessage: 'Powerful performance monitoring', + } + )} + + + +
); diff --git a/x-pack/plugins/search_indices/public/components/start/hooks/use_coding_examples.tsx b/x-pack/plugins/search_indices/public/components/start/hooks/use_coding_examples.tsx new file mode 100644 index 0000000000000..1a351d10943f2 --- /dev/null +++ b/x-pack/plugins/search_indices/public/components/start/hooks/use_coding_examples.tsx @@ -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. + */ + +import { CreateIndexCodeExamples } from '../../../types'; +import { DenseVectorSeverlessCodeExamples } from '../../../code_examples/create_index'; + +export const useStartPageCodingExamples = (): CreateIndexCodeExamples => { + // TODO: in the future this will be dynamic based on the onboarding token + // or project sub-type + return DenseVectorSeverlessCodeExamples; +}; diff --git a/x-pack/plugins/search_indices/public/components/start/types.ts b/x-pack/plugins/search_indices/public/components/start/types.ts index 6b6c1c8e38f61..c0dbbeca88883 100644 --- a/x-pack/plugins/search_indices/public/components/start/types.ts +++ b/x-pack/plugins/search_indices/public/components/start/types.ts @@ -5,6 +5,9 @@ * 2.0. */ +import type { AvailableLanguages } from '../../code_examples'; + export interface CreateIndexFormState { indexName: string; + codingLanguage: AvailableLanguages; } diff --git a/x-pack/plugins/search_indices/public/plugin.ts b/x-pack/plugins/search_indices/public/plugin.ts index 5ebfb84e1cd39..bec4f7cb7bfe6 100644 --- a/x-pack/plugins/search_indices/public/plugin.ts +++ b/x-pack/plugins/search_indices/public/plugin.ts @@ -7,6 +7,8 @@ import type { CoreSetup, CoreStart, Plugin } from '@kbn/core/public'; import { i18n } from '@kbn/i18n'; + +import { docLinks } from '../common/doc_links'; import type { SearchIndicesAppPluginStartDependencies, SearchIndicesPluginSetup, @@ -64,6 +66,7 @@ export class SearchIndicesPlugin } public start(core: CoreStart): SearchIndicesPluginStart { + docLinks.setDocLinks(core.docLinks.links); return {}; } diff --git a/x-pack/plugins/search_indices/public/types.ts b/x-pack/plugins/search_indices/public/types.ts index 95f5eb2883d2e..a3e63df2642b3 100644 --- a/x-pack/plugins/search_indices/public/types.ts +++ b/x-pack/plugins/search_indices/public/types.ts @@ -77,6 +77,7 @@ export interface CreateIndexCodeDefinition { } export interface CreateIndexCodeExamples { + exampleType: string; sense: CreateIndexCodeDefinition; curl: CreateIndexCodeDefinition; python: CreateIndexCodeDefinition; diff --git a/x-pack/test_serverless/functional/page_objects/svl_search_elasticsearch_start_page.ts b/x-pack/test_serverless/functional/page_objects/svl_search_elasticsearch_start_page.ts index 33dbc6f693ea8..798d396258e75 100644 --- a/x-pack/test_serverless/functional/page_objects/svl_search_elasticsearch_start_page.ts +++ b/x-pack/test_serverless/functional/page_objects/svl_search_elasticsearch_start_page.ts @@ -30,6 +30,11 @@ export function SvlSearchElasticsearchStartPageProvider({ getService }: FtrProvi ); }); }, + async expectToBeOnMLFileUploadPage() { + await retry.tryForTime(60 * 1000, async () => { + expect(await browser.getCurrentUrl()).contain('/app/ml/filedatavisualizer'); + }); + }, async expectIndexNameToExist() { await testSubjects.existOrFail('indexNameField'); }, @@ -67,5 +72,23 @@ export function SvlSearchElasticsearchStartPageProvider({ getService }: FtrProvi await testSubjects.existOrFail('createIndexCodeViewBtn'); await testSubjects.click('createIndexCodeViewBtn'); }, + async clickFileUploadLink() { + await testSubjects.existOrFail('uploadFileLink'); + await testSubjects.click('uploadFileLink'); + }, + async expectAnalyzeLogsLink() { + await testSubjects.existOrFail('analyzeLogsBtn'); + expect(await testSubjects.getAttribute('analyzeLogsBtn', 'href')).equal( + 'https://docs.elastic.co/serverless/elasticsearch/ingest-your-data' + ); + expect(await testSubjects.getAttribute('analyzeLogsBtn', 'target')).equal('_blank'); + }, + async expectO11yTrialLink() { + await testSubjects.existOrFail('startO11yTrialBtn'); + expect(await testSubjects.getAttribute('startO11yTrialBtn', 'href')).equal( + 'https://fake-cloud.elastic.co/projects/create/observability/start' + ); + expect(await testSubjects.getAttribute('startO11yTrialBtn', 'target')).equal('_blank'); + }, }; } diff --git a/x-pack/test_serverless/functional/test_suites/search/config.feature_flags.ts b/x-pack/test_serverless/functional/test_suites/search/config.feature_flags.ts index 05eb6136bf008..824d145282257 100644 --- a/x-pack/test_serverless/functional/test_suites/search/config.feature_flags.ts +++ b/x-pack/test_serverless/functional/test_suites/search/config.feature_flags.ts @@ -19,10 +19,11 @@ export default createTestConfig({ suiteTags: { exclude: ['skipSvlSearch'] }, // add feature flags kbnServerArgs: [ - `--xpack.cloud.id='ES3_FTR_TESTS:ZmFrZS1kb21haW4uY2xkLmVsc3RjLmNvJGZha2Vwcm9qZWN0aWQuZXMkZmFrZXByb2plY3RpZC5rYg=='`, - `--xpack.cloud.serverless.project_id='fakeprojectid'`, - `--xpack.cloud.base_url='https://cloud.elastic.co'`, - `--xpack.cloud.organization_url='/account/members'`, + `--xpack.cloud.id=ES3_FTR_TESTS:ZmFrZS1kb21haW4uY2xkLmVsc3RjLmNvJGZha2Vwcm9qZWN0aWQuZXMkZmFrZXByb2plY3RpZC5rYg==`, + `--xpack.cloud.serverless.project_id=fakeprojectid`, + `--xpack.cloud.base_url=https://fake-cloud.elastic.co`, + `--xpack.cloud.projects_url=/projects/`, + `--xpack.cloud.organization_url=/account/members`, `--xpack.security.roleManagementEnabled=true`, `--xpack.spaces.maxSpaces=100`, // enables spaces UI capabilities `--xpack.searchIndices.enabled=true`, // global empty state FF diff --git a/x-pack/test_serverless/functional/test_suites/search/config.ts b/x-pack/test_serverless/functional/test_suites/search/config.ts index 6853e75d987b8..4739cde53bf86 100644 --- a/x-pack/test_serverless/functional/test_suites/search/config.ts +++ b/x-pack/test_serverless/functional/test_suites/search/config.ts @@ -19,7 +19,9 @@ export default createTestConfig({ // https://github.com/elastic/project-controller/blob/main/internal/project/esproject/config/elasticsearch.yml esServerArgs: [], kbnServerArgs: [ - `--xpack.cloud.id='ES3_FTR_TESTS:ZmFrZS1kb21haW4uY2xkLmVsc3RjLmNvJGZha2Vwcm9qZWN0aWQuZXMkZmFrZXByb2plY3RpZC5rYg=='`, - `--xpack.cloud.serverless.project_id='fakeprojectid'`, + `--xpack.cloud.id=ES3_FTR_TESTS:ZmFrZS1kb21haW4uY2xkLmVsc3RjLmNvJGZha2Vwcm9qZWN0aWQuZXMkZmFrZXByb2plY3RpZC5rYg==`, + `--xpack.cloud.serverless.project_id=fakeprojectid`, + `--xpack.cloud.base_url=https://fake-cloud.elastic.co`, + `--xpack.cloud.projects_url=/projects/`, ], }); diff --git a/x-pack/test_serverless/functional/test_suites/search/elasticsearch_start.ts b/x-pack/test_serverless/functional/test_suites/search/elasticsearch_start.ts index 55f1551141e47..f6362a409658e 100644 --- a/x-pack/test_serverless/functional/test_suites/search/elasticsearch_start.ts +++ b/x-pack/test_serverless/functional/test_suites/search/elasticsearch_start.ts @@ -81,6 +81,18 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await pageObjects.svlSearchElasticsearchStartPage.clickUIViewButton(); await pageObjects.svlSearchElasticsearchStartPage.expectCreateIndexUIView(); }); + + it('should have file upload link', async () => { + await pageObjects.svlSearchElasticsearchStartPage.expectToBeOnStartPage(); + await pageObjects.svlSearchElasticsearchStartPage.clickFileUploadLink(); + await pageObjects.svlSearchElasticsearchStartPage.expectToBeOnMLFileUploadPage(); + }); + + it('should have o11y links', async () => { + await pageObjects.svlSearchElasticsearchStartPage.expectToBeOnStartPage(); + await pageObjects.svlSearchElasticsearchStartPage.expectAnalyzeLogsLink(); + await pageObjects.svlSearchElasticsearchStartPage.expectO11yTrialLink(); + }); }); describe('viewer', function () { before(async () => {