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
### 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 () => {