[Search][Onboarding] Default home to Global Empty State (#195142)

## Summary
Updated the ES3 (Serverless Search) default home route to be the global
empty state, when `search_indices` is enabled.
Moved the getting started page, the current homepage, from
`/app/elasticsearch` to `/app/elasticsearch/getting_started`
This required adding a redirect for `/app/elasticsearch` to
`/app/elasticsearch/start`.

After we enabled `search_indices` by default for ES3, we can remove the
conditional logic added by this PR.

### Screenshots
ES3 Home With search indices config FF enabled

![image](https://github.com/user-attachments/assets/9a2227c0-8ec3-4e98-ba5c-08cebf8d3df4)
ES3 Home with search indices config FF disabled

![image](https://github.com/user-attachments/assets/68bb6f36-f754-4f6b-9637-cf419ef21945)


### Checklist

- [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
- [ ] [Flaky Test
Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was
used on any tests changed
This commit is contained in:
Rodney Norris 2024-10-08 09:29:59 -05:00 committed by GitHub
parent d20c579304
commit d573915dd3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
24 changed files with 234 additions and 83 deletions

View file

@ -19,3 +19,5 @@ export const SERVERLESS_ES_CONNECTORS_ID = 'serverlessConnectors';
export const SERVERLESS_ES_SEARCH_PLAYGROUND_ID = 'searchPlayground';
export const SERVERLESS_ES_SEARCH_INFERENCE_ENDPOINTS_ID = 'searchInferenceEndpoints';
export const SEARCH_HOMEPAGE = 'searchHomepage';
export const SEARCH_INDICES_START = 'elasticsearchStart';
export const SEARCH_INDICES = 'elasticsearchIndices';

View file

@ -20,6 +20,8 @@ import {
SERVERLESS_ES_SEARCH_PLAYGROUND_ID,
SERVERLESS_ES_SEARCH_INFERENCE_ENDPOINTS_ID,
SEARCH_HOMEPAGE,
SEARCH_INDICES_START,
SEARCH_INDICES,
} from './constants';
export type EnterpriseSearchApp = typeof ENTERPRISE_SEARCH_APP_ID;
@ -34,6 +36,8 @@ export type ConnectorsId = typeof SERVERLESS_ES_CONNECTORS_ID;
export type SearchPlaygroundId = typeof SERVERLESS_ES_SEARCH_PLAYGROUND_ID;
export type SearchInferenceEndpointsId = typeof SERVERLESS_ES_SEARCH_INFERENCE_ENDPOINTS_ID;
export type SearchHomepage = typeof SEARCH_HOMEPAGE;
export type SearchStart = typeof SEARCH_INDICES_START;
export type SearchIndices = typeof SEARCH_INDICES;
export type ContentLinkId = 'searchIndices' | 'connectors' | 'webCrawlers';
@ -59,4 +63,6 @@ export type DeepLinkId =
| `${EnterpriseSearchContentApp}:${ContentLinkId}`
| `${EnterpriseSearchApplicationsApp}:${ApplicationsLinkId}`
| `${EnterpriseSearchAppsearchApp}:${AppsearchLinkId}`
| `${EnterpriseSearchRelevanceApp}:${RelevanceLinkId}`;
| `${EnterpriseSearchRelevanceApp}:${RelevanceLinkId}`
| SearchStart
| SearchIndices;

View file

@ -5,7 +5,11 @@
* 2.0.
*/
import type { SearchIndices, SearchStart } from '@kbn/deeplinks-search/deep_links';
export const PLUGIN_ID = 'searchIndices';
export const PLUGIN_NAME = 'searchIndices';
export const START_APP_ID: SearchStart = 'elasticsearchStart';
export const INDICES_APP_ID: SearchIndices = 'elasticsearchIndices';
export type { IndicesStatusResponse, UserStartPrivilegesResponse } from './types';

View file

@ -56,13 +56,17 @@ export const CreateIndexForm = ({
const [indexNameHasError, setIndexNameHasError] = useState<boolean>(false);
const usageTracker = useUsageTracker();
const { createIndex, isLoading } = useCreateIndex();
const onCreateIndex = useCallback(() => {
if (!isValidIndexName(formState.indexName)) {
return;
}
usageTracker.click(AnalyticsEvents.startCreateIndexClick);
createIndex({ indexName: formState.indexName });
}, [usageTracker, createIndex, formState.indexName]);
const onCreateIndex = useCallback(
(e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
if (!isValidIndexName(formState.indexName)) {
return;
}
usageTracker.click(AnalyticsEvents.startCreateIndexClick);
createIndex({ indexName: formState.indexName });
},
[usageTracker, createIndex, formState.indexName]
);
const onIndexNameChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const newIndexName = e.target.value;
setFormState({ ...formState, indexName: e.target.value });
@ -78,7 +82,12 @@ export const CreateIndexForm = ({
return (
<>
<EuiForm data-test-subj="createIndexUIView" fullWidth component="form">
<EuiForm
data-test-subj="createIndexUIView"
fullWidth
component="form"
onSubmit={onCreateIndex}
>
<EuiFormRow
label={i18n.translate('xpack.searchIndices.startPage.createIndex.name.label', {
defaultMessage: 'Name your index',
@ -137,11 +146,9 @@ export const CreateIndexForm = ({
color="primary"
iconSide="left"
iconType="sparkles"
data-telemetry-id="searchIndices-start-createIndexBtn"
data-test-subj="createIndexBtn"
disabled={indexNameHasError || isLoading}
isLoading={isLoading}
onClick={onCreateIndex}
type="submit"
>
{CREATE_INDEX_CONTENT}
@ -181,11 +188,7 @@ export const CreateIndexForm = ({
defaultMessage="Already have some data? {link}"
values={{
link: (
<EuiLink
data-telemetry-id="searchIndices-start-uploadFile"
data-test-subj="uploadFileLink"
onClick={onFileUpload}
>
<EuiLink data-test-subj="uploadFileLink" onClick={onFileUpload}>
{i18n.translate(
'xpack.searchIndices.startPage.createIndex.fileUpload.link',
{

View file

@ -221,7 +221,6 @@ export const ElasticsearchStart = ({ userPrivileges }: ElasticsearchStartProps)
iconSide="right"
iconType="popout"
data-test-subj="analyzeLogsBtn"
data-telemetry-id="searchIndicesStartCollectLogsLink"
href={docLinks.analyzeLogs}
target="_blank"
>
@ -249,7 +248,6 @@ export const ElasticsearchStart = ({ userPrivileges }: ElasticsearchStartProps)
iconSide="right"
iconType="popout"
data-test-subj="startO11yTrialBtn"
data-telemetry-id="searchIndicesStartO11yTrialLink"
href={o11yTrialLink}
target="_blank"
>

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { useEffect } from 'react';
import { useEffect, useState } from 'react';
import type { IndicesStatusResponse } from '../../../../common';
@ -15,13 +15,30 @@ import { navigateToIndexDetails } from './utils';
export const useIndicesRedirect = (indicesStatus?: IndicesStatusResponse) => {
const { application, http } = useKibana().services;
const [lastStatus, setLastStatus] = useState<IndicesStatusResponse | undefined>(() => undefined);
const [hasDoneRedirect, setHasDoneRedirect] = useState(() => false);
return useEffect(() => {
if (!indicesStatus) return;
if (indicesStatus.indexNames.length === 0) return;
if (hasDoneRedirect) {
return;
}
if (!indicesStatus) {
return;
}
if (indicesStatus.indexNames.length === 0) {
setLastStatus(indicesStatus);
return;
}
if (lastStatus === undefined && indicesStatus.indexNames.length > 0) {
application.navigateToApp('management', { deepLinkId: 'index_management' });
setHasDoneRedirect(true);
return;
}
if (indicesStatus.indexNames.length === 1) {
navigateToIndexDetails(application, http, indicesStatus.indexNames[0]);
setHasDoneRedirect(true);
return;
}
application.navigateToApp('management', { deepLinkId: 'index_management' });
}, [application, http, indicesStatus]);
setHasDoneRedirect(true);
}, [application, http, indicesStatus, lastStatus, hasDoneRedirect]);
};

View file

@ -16,6 +16,8 @@ import type {
SearchIndicesServicesContextDeps,
} from './types';
import { initQueryClient } from './services/query_client';
import { INDICES_APP_ID, START_APP_ID } from '../common';
import { INDICES_APP_BASE, START_APP_BASE } from './routes';
export class SearchIndicesPlugin
implements Plugin<SearchIndicesPluginSetup, SearchIndicesPluginStart>
@ -26,8 +28,8 @@ export class SearchIndicesPlugin
const queryClient = initQueryClient(core.notifications.toasts);
core.application.register({
id: 'elasticsearchStart',
appRoute: '/app/elasticsearch/start',
id: START_APP_ID,
appRoute: START_APP_BASE,
title: i18n.translate('xpack.searchIndices.elasticsearchStart.startAppTitle', {
defaultMessage: 'Elasticsearch Start',
}),
@ -43,8 +45,8 @@ export class SearchIndicesPlugin
},
});
core.application.register({
id: 'elasticsearchIndices',
appRoute: '/app/elasticsearch/indices',
id: INDICES_APP_ID,
appRoute: INDICES_APP_BASE,
title: i18n.translate('xpack.searchIndices.elasticsearchIndices.startAppTitle', {
defaultMessage: 'Elasticsearch Indices',
}),
@ -62,12 +64,18 @@ export class SearchIndicesPlugin
return {
enabled: true,
startAppId: START_APP_ID,
startRoute: START_APP_BASE,
};
}
public start(core: CoreStart): SearchIndicesPluginStart {
docLinks.setDocLinks(core.docLinks.links);
return {};
return {
enabled: true,
startAppId: START_APP_ID,
startRoute: START_APP_BASE,
};
}
public stop() {}

View file

@ -13,3 +13,6 @@ export enum SearchIndexDetailsTabs {
MAPPINGS = 'mappings',
SETTINGS = 'settings',
}
export const START_APP_BASE = '/app/elasticsearch/start';
export const INDICES_APP_BASE = '/app/elasticsearch/indices';

View file

@ -15,13 +15,20 @@ import type {
MappingProperty,
MappingPropertyBase,
} from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
import { IndexManagementPluginStart } from '@kbn/index-management-shared-types';
import type { IndexManagementPluginStart } from '@kbn/index-management-shared-types';
import type { AppDeepLinkId } from '@kbn/core-chrome-browser';
export interface SearchIndicesPluginSetup {
enabled: boolean;
startAppId: string;
startRoute: string;
}
export interface SearchIndicesPluginStart {
enabled: boolean;
startAppId: AppDeepLinkId;
startRoute: string;
}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface SearchIndicesPluginStart {}
export interface AppPluginStartDependencies {
navigation: NavigationPublicPluginStart;

View file

@ -36,7 +36,9 @@
"@kbn/es-types",
"@kbn/search-api-keys-server",
"@kbn/search-api-keys-components",
"@kbn/search-shared-ui"
"@kbn/search-shared-ui",
"@kbn/deeplinks-search",
"@kbn/core-chrome-browser"
],
"exclude": [
"target/**/*",

View file

@ -5,11 +5,27 @@
* 2.0.
*/
import type { NavigationTreeDefinition } from '@kbn/core-chrome-browser';
import type {
AppDeepLinkId,
NavigationTreeDefinition,
NodeDefinition,
} from '@kbn/core-chrome-browser';
import { i18n } from '@kbn/i18n';
import { CONNECTORS_LABEL } from '../common/i18n_string';
export const navigationTree = (): NavigationTreeDefinition => ({
const gettingStartedItem: NodeDefinition<AppDeepLinkId, string, string> = {
id: 'gettingStarted',
title: i18n.translate('xpack.serverlessSearch.nav.gettingStarted', {
defaultMessage: 'Getting Started',
}),
link: 'serverlessElasticsearch',
spaceBefore: 'm',
};
export const navigationTree = (
homeLink: AppDeepLinkId = 'serverlessElasticsearch' as AppDeepLinkId,
showGettingStarted: boolean
): NavigationTreeDefinition => ({
body: [
{
type: 'navGroup',
@ -25,7 +41,7 @@ export const navigationTree = (): NavigationTreeDefinition => ({
title: i18n.translate('xpack.serverlessSearch.nav.home', {
defaultMessage: 'Home',
}),
link: 'serverlessElasticsearch',
link: homeLink,
spaceBefore: 'm',
},
{
@ -70,6 +86,16 @@ export const navigationTree = (): NavigationTreeDefinition => ({
link: 'management:index_management',
breadcrumbStatus:
'hidden' /* management sub-pages set their breadcrumbs themselves */,
getIsActive: ({ pathNameSerialized, prepend }) => {
return (
pathNameSerialized.startsWith(
prepend('/app/management/data/index_management/')
) ||
pathNameSerialized.startsWith(
prepend('/app/elasticsearch/indices/index_details/')
)
);
},
},
{
title: CONNECTORS_LABEL,
@ -112,6 +138,7 @@ export const navigationTree = (): NavigationTreeDefinition => ({
},
],
},
...(showGettingStarted ? [gettingStartedItem] : []),
],
},
],

View file

@ -73,6 +73,10 @@ export class ServerlessSearchPlugin
const homeTitle = i18n.translate('xpack.serverlessSearch.app.home.title', {
defaultMessage: 'Home',
});
const useGlobalEmptyState = setupDeps.searchIndices?.enabled ?? false;
const serverlessElasticsearchAppRoute = useGlobalEmptyState
? '/app/elasticsearch/getting_started'
: '/app/elasticsearch';
core.application.register({
id: 'serverlessElasticsearch',
@ -81,7 +85,7 @@ export class ServerlessSearchPlugin
}),
euiIconType: 'logoElastic',
category: DEFAULT_APP_CATEGORIES.enterpriseSearch,
appRoute: '/app/elasticsearch',
appRoute: serverlessElasticsearchAppRoute,
async mount({ element, history }: AppMountParameters) {
const { renderApp } = await import('./application/elasticsearch');
const [coreStart, services] = await core.getStartServices();
@ -120,6 +124,24 @@ export class ServerlessSearchPlugin
},
});
if (useGlobalEmptyState) {
const redirectApp = setupDeps.searchIndices!.startAppId;
core.application.register({
id: 'serverlessHomeRedirect',
title: homeTitle,
appRoute: '/app/elasticsearch',
euiIconType: 'logoElastic',
category: DEFAULT_APP_CATEGORIES.enterpriseSearch,
visibleIn: [],
async mount({}: AppMountParameters) {
const [coreStart] = await core.getStartServices();
coreStart.chrome.docTitle.change(homeTitle);
coreStart.application.navigateToApp(redirectApp);
return () => {};
},
});
}
setupDeps.discover.showInlineTopNav();
return {};
@ -130,10 +152,15 @@ export class ServerlessSearchPlugin
services: ServerlessSearchPluginStartDependencies
): ServerlessSearchPluginStart {
const { serverless, management, indexManagement, security } = services;
const useGlobalEmptyState = services.searchIndices?.enabled ?? false;
const homeRoute = useGlobalEmptyState
? services.searchIndices!.startRoute
: '/app/elasticsearch';
serverless.setProjectHome(homeRoute);
serverless.setProjectHome('/app/elasticsearch');
const navigationTree$ = of(navigationTree());
const navigationTree$ = of(
navigationTree(services.searchIndices?.startAppId, useGlobalEmptyState)
);
serverless.initNavigation('search', navigationTree$, { dataTestSubj: 'svlSearchSideNav' });
const extendCardNavDefinitions = serverless.getNavigationCards(

View file

@ -15,6 +15,10 @@ import type { ServerlessPluginSetup, ServerlessPluginStart } from '@kbn/serverle
import type { SharePluginStart } from '@kbn/share-plugin/public';
import type { IndexManagementPluginStart } from '@kbn/index-management-plugin/public';
import type { DiscoverSetup } from '@kbn/discover-plugin/public';
import type {
SearchIndicesPluginSetup,
SearchIndicesPluginStart,
} from '@kbn/search-indices/public';
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface ServerlessSearchPluginSetup {}
@ -27,6 +31,7 @@ export interface ServerlessSearchPluginSetupDependencies {
management: ManagementSetup;
serverless: ServerlessPluginSetup;
discover: DiscoverSetup;
searchIndices?: SearchIndicesPluginSetup;
}
export interface ServerlessSearchPluginStartDependencies {
@ -39,4 +44,5 @@ export interface ServerlessSearchPluginStartDependencies {
serverless: ServerlessPluginStart;
share: SharePluginStart;
indexManagement?: IndexManagementPluginStart;
searchIndices?: SearchIndicesPluginStart;
}

View file

@ -51,5 +51,6 @@
"@kbn/security-api-key-management",
"@kbn/search-inference-endpoints",
"@kbn/security-plugin-types-common",
"@kbn/search-indices",
]
}

View file

@ -116,6 +116,7 @@ export function createTestConfig(options: CreateTestConfigOptions) {
integrations: {
pathname: '/app/integrations',
},
...(options.apps ?? {}),
},
// choose where screenshots should be saved
screenshots: {

View file

@ -22,12 +22,20 @@ export function SvlSearchNavigationServiceProvider({
await testSubjects.existOrFail('svlSearchOverviewPage', { timeout: 2000 });
});
},
async navigateToElasticsearchStartPage() {
async navigateToGettingStartedPage() {
await retry.tryForTime(60 * 1000, async () => {
await PageObjects.common.navigateToApp('elasticsearch/start', {
await PageObjects.common.navigateToApp('serverlessElasticsearch');
await testSubjects.existOrFail('svlSearchOverviewPage', { timeout: 2000 });
});
},
async navigateToElasticsearchStartPage(expectRedirect: boolean = false) {
await retry.tryForTime(60 * 1000, async () => {
await PageObjects.common.navigateToApp('elasticsearchStart', {
shouldLoginIfPrompted: false,
});
await testSubjects.existOrFail('elasticsearchStartPage', { timeout: 2000 });
if (!expectRedirect) {
await testSubjects.existOrFail('elasticsearchStartPage', { timeout: 2000 });
}
});
},
async navigateToIndexDetailPage(indexName: string) {

View file

@ -34,4 +34,15 @@ export default createTestConfig({
// include settings from project controller
// https://github.com/elastic/project-controller/blob/main/internal/project/esproject/config/elasticsearch.yml
esServerArgs: ['xpack.security.authc.native_roles.enabled=true'],
apps: {
serverlessElasticsearch: {
pathname: '/app/elasticsearch/getting_started',
},
elasticsearchStart: {
pathname: '/app/elasticsearch/start',
},
elasticsearchIndices: {
pathname: '/app/elasticsearch/indices',
},
},
});

View file

@ -24,4 +24,15 @@ export default createTestConfig({
`--xpack.cloud.base_url=https://fake-cloud.elastic.co`,
`--xpack.cloud.projects_url=/projects/`,
],
apps: {
serverlessElasticsearch: {
pathname: '/app/elasticsearch',
},
serverlessConnectors: {
pathname: '/app/connectors',
},
searchPlayground: {
pathname: '/app/search_playground',
},
},
});

View file

@ -26,8 +26,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
await esDeleteAllIndices(['search-*', 'test-*']);
};
// Failing: See https://github.com/elastic/kibana/issues/194673
describe.skip('Elasticsearch Start [Onboarding Empty State]', function () {
describe('Elasticsearch Start [Onboarding Empty State]', function () {
describe('developer', function () {
before(async () => {
await pageObjects.svlCommonPage.loginWithRole('developer');
@ -77,6 +76,12 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
await es.indices.create({ index: 'test-my-index-002' });
await pageObjects.svlSearchElasticsearchStartPage.expectToBeOnIndexListPage();
});
it('should redirect to indices list if single index exist on page load', async () => {
await svlSearchNavigation.navigateToGettingStartedPage();
await es.indices.create({ index: 'test-my-index-001' });
await svlSearchNavigation.navigateToElasticsearchStartPage(true);
await pageObjects.svlSearchElasticsearchStartPage.expectToBeOnIndexListPage();
});
it('should support switching between UI and Code Views', async () => {
await pageObjects.svlSearchElasticsearchStartPage.expectToBeOnStartPage();
@ -87,7 +92,8 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
await pageObjects.svlSearchElasticsearchStartPage.expectCreateIndexUIView();
});
it('should show the api key in code view', async () => {
// Failing: See https://github.com/elastic/kibana/issues/194673
it.skip('should show the api key in code view', async () => {
await pageObjects.svlSearchElasticsearchStartPage.expectToBeOnStartPage();
await pageObjects.svlSearchElasticsearchStartPage.clickCodeViewButton();
await pageObjects.svlApiKeys.expectAPIKeyAvailable();
@ -125,7 +131,8 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
await pageObjects.svlApiKeys.expectAPIKeyAvailable();
});
it('Same API Key should be present on start page and index detail view', async () => {
// Failing: See https://github.com/elastic/kibana/issues/194673
it.skip('Same API Key should be present on start page and index detail view', async () => {
await pageObjects.svlSearchElasticsearchStartPage.clickCodeViewButton();
await pageObjects.svlApiKeys.expectAPIKeyAvailable();
const apiKeyUI = await pageObjects.svlApiKeys.getAPIKeyFromUI();
@ -151,41 +158,40 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
await pageObjects.svlSearchElasticsearchStartPage.expectAnalyzeLogsLink();
await pageObjects.svlSearchElasticsearchStartPage.expectO11yTrialLink();
});
});
describe('viewer', function () {
before(async () => {
await pageObjects.svlCommonPage.loginAsViewer();
await deleteAllTestIndices();
});
beforeEach(async () => {
await svlSearchNavigation.navigateToElasticsearchStartPage();
});
after(async () => {
await deleteAllTestIndices();
});
describe('viewer', function () {
before(async () => {
await pageObjects.svlCommonPage.loginAsViewer();
await deleteAllTestIndices();
});
beforeEach(async () => {
await svlSearchNavigation.navigateToElasticsearchStartPage();
});
after(async () => {
await deleteAllTestIndices();
});
it('should default to code view when lacking create index permissions', async () => {
await pageObjects.svlSearchElasticsearchStartPage.expectToBeOnStartPage();
await pageObjects.svlSearchElasticsearchStartPage.expectCreateIndexCodeView();
await pageObjects.svlSearchElasticsearchStartPage.clickUIViewButton();
await pageObjects.svlSearchElasticsearchStartPage.expectCreateIndexUIView();
await pageObjects.svlSearchElasticsearchStartPage.expectCreateIndexButtonToBeDisabled();
});
it('should default to code view when lacking create index permissions', async () => {
await pageObjects.svlSearchElasticsearchStartPage.expectToBeOnStartPage();
await pageObjects.svlSearchElasticsearchStartPage.expectCreateIndexCodeView();
await pageObjects.svlSearchElasticsearchStartPage.clickUIViewButton();
await pageObjects.svlSearchElasticsearchStartPage.expectCreateIndexUIView();
await pageObjects.svlSearchElasticsearchStartPage.expectCreateIndexButtonToBeDisabled();
});
it('should not create an API key if the user only has viewer permissions', async () => {
await pageObjects.svlSearchElasticsearchStartPage.expectToBeOnStartPage();
await pageObjects.svlSearchElasticsearchStartPage.clickCodeViewButton();
await pageObjects.svlSearchElasticsearchStartPage.expectAPIKeyFormNotAvailable();
const apiKey = await pageObjects.svlApiKeys.getAPIKeyFromSessionStorage();
expect(apiKey).to.be(null);
});
it('should not create an API key if the user only has viewer permissions', async () => {
await pageObjects.svlSearchElasticsearchStartPage.expectToBeOnStartPage();
await pageObjects.svlSearchElasticsearchStartPage.clickCodeViewButton();
await pageObjects.svlSearchElasticsearchStartPage.expectAPIKeyFormNotAvailable();
const apiKey = await pageObjects.svlApiKeys.getAPIKeyFromSessionStorage();
expect(apiKey).to.be(null);
});
it('should redirect to index details when index is created via API', async () => {
await pageObjects.svlSearchElasticsearchStartPage.expectToBeOnStartPage();
await pageObjects.svlSearchElasticsearchStartPage.expectCreateIndexCodeView();
await es.indices.create({ index: 'test-my-api-index' });
await pageObjects.svlSearchElasticsearchStartPage.expectToBeOnIndexDetailsPage();
});
it('should redirect to index details when index is created via API', async () => {
await pageObjects.svlSearchElasticsearchStartPage.expectToBeOnStartPage();
await pageObjects.svlSearchElasticsearchStartPage.expectCreateIndexCodeView();
await es.indices.create({ index: 'test-my-api-index' });
await pageObjects.svlSearchElasticsearchStartPage.expectToBeOnIndexDetailsPage();
});
});
});

View file

@ -13,13 +13,13 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
const pageObjects = getPageObjects(['svlSearchLandingPage', 'svlCommonPage', 'embeddedConsole']);
const svlSearchNavigation = getService('svlSearchNavigation');
describe('landing page', function () {
describe('getting started', function () {
before(async () => {
await pageObjects.svlCommonPage.loginAsViewer();
});
it('has serverless side nav', async () => {
await svlSearchNavigation.navigateToLandingPage();
await svlSearchNavigation.navigateToGettingStartedPage();
await pageObjects.svlSearchLandingPage.assertSvlSearchSideNavExists();
});
@ -44,7 +44,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
describe('API Key creation', () => {
beforeEach(async () => {
// We need to reload the page between api key creations
await svlSearchNavigation.navigateToLandingPage();
await svlSearchNavigation.navigateToGettingStartedPage();
});
it('can create an API key that expires', async () => {
@ -86,7 +86,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
describe('Pipelines', () => {
beforeEach(async () => {
await svlSearchNavigation.navigateToLandingPage();
await svlSearchNavigation.navigateToGettingStartedPage();
});
it('can redirect to the pipeline creation index page', async () => {
await pageObjects.svlSearchLandingPage.pipeline.createPipeline();

View file

@ -12,6 +12,7 @@ export default function ({ loadTestFile }: FtrProviderContext) {
// add tests that require feature flags, defined in config.feature_flags.ts
loadTestFile(require.resolve('./elasticsearch_start.ts'));
loadTestFile(require.resolve('./search_index_detail.ts'));
loadTestFile(require.resolve('./getting_started'));
loadTestFile(require.resolve('../common/platform_security/navigation/management_nav_cards.ts'));
loadTestFile(require.resolve('../common/platform_security/roles.ts'));
loadTestFile(require.resolve('../common/spaces/multiple_spaces_enabled.ts'));

View file

@ -11,7 +11,7 @@ export default function ({ loadTestFile }: FtrProviderContext) {
describe('serverless search UI', function () {
this.tags(['esGate']);
loadTestFile(require.resolve('./landing_page'));
loadTestFile(require.resolve('./getting_started'));
loadTestFile(require.resolve('./connectors/connectors_overview'));
loadTestFile(require.resolve('./default_dataview'));
loadTestFile(require.resolve('./navigation'));

View file

@ -84,7 +84,8 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
await pageObjects.embeddedConsole.clickEmbeddedConsoleControlBar();
});
it('should show api key', async () => {
// Failing: See https://github.com/elastic/kibana/issues/194673
it.skip('should show api key', async () => {
await pageObjects.svlApiKeys.expectAPIKeyAvailable();
const apiKey = await pageObjects.svlApiKeys.getAPIKeyFromUI();
await pageObjects.svlSearchIndexDetailPage.expectAPIKeyToBeVisibleInCodeBlock(apiKey);

View file

@ -16,4 +16,5 @@ export interface CreateTestConfigOptions {
junit: { reportName: string };
suiteTags?: { include?: string[]; exclude?: string[] };
services?: InheritedServices;
apps?: Record<string, { pathname: string; hash?: string }>;
}