From 53f3e28dcf966f8f4a80fb4bdd4ca2915bf094ca Mon Sep 17 00:00:00 2001 From: Julia Rechkunova Date: Wed, 25 Sep 2024 00:08:21 +0300 Subject: [PATCH] [Discover] Extend EBT context with a list of activated context-aware profiles (#192908) - Closes https://github.com/elastic/kibana/issues/186109 ## Summary This PR extends EBT context with `dscProfiles` - a list of active context-aware profiles. Screenshot 2024-09-16 at 17 30 47 ## Testing Enable "Usage collection" global setting. Navigate to Discover and observe `kibana-browser` requests in Network tab. ### 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 --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> (cherry picked from commit c28af871d2fa4d8e9f0edd0eafad4d10669a62f5) --- src/plugins/discover/public/build_services.ts | 5 + .../context_awareness/__mocks__/index.tsx | 6 +- .../profiles_manager.test.ts | 6 ++ .../context_awareness/profiles_manager.ts | 16 ++- src/plugins/discover/public/plugin.tsx | 46 ++++++-- .../discover_ebt_context_manager.test.ts | 95 ++++++++++++++++ .../services/discover_ebt_context_manager.ts | 75 +++++++++++++ src/plugins/discover/tsconfig.json | 3 +- .../context_awareness/_data_source_profile.ts | 101 +++++++++++++++++- .../apps/discover/context_awareness/config.ts | 14 +++ .../apps/discover/ftr_provider_context.d.ts | 6 ++ 11 files changed, 361 insertions(+), 12 deletions(-) create mode 100644 src/plugins/discover/public/services/discover_ebt_context_manager.test.ts create mode 100644 src/plugins/discover/public/services/discover_ebt_context_manager.ts diff --git a/src/plugins/discover/public/build_services.ts b/src/plugins/discover/public/build_services.ts index 7bb52691fd4a4..f4ee14fcf04f7 100644 --- a/src/plugins/discover/public/build_services.ts +++ b/src/plugins/discover/public/build_services.ts @@ -63,6 +63,7 @@ import type { DiscoverContextAppLocator } from './application/context/services/l import type { DiscoverSingleDocLocator } from './application/doc/locator'; import type { DiscoverAppLocator } from '../common'; import type { ProfilesManager } from './context_awareness'; +import type { DiscoverEBTContextManager } from './services/discover_ebt_context_manager'; /** * Location state of internal Discover history instance @@ -130,6 +131,7 @@ export interface DiscoverServices { noDataPage?: NoDataPagePluginStart; observabilityAIAssistant?: ObservabilityAIAssistantPublicStart; profilesManager: ProfilesManager; + ebtContextManager: DiscoverEBTContextManager; fieldsMetadata?: FieldsMetadataPublicStart; } @@ -145,6 +147,7 @@ export const buildServices = memoize( scopedHistory, urlTracker, profilesManager, + ebtContextManager, setHeaderActionMenu = noop, }: { core: CoreStart; @@ -157,6 +160,7 @@ export const buildServices = memoize( scopedHistory?: ScopedHistory; urlTracker: UrlTracker; profilesManager: ProfilesManager; + ebtContextManager: DiscoverEBTContextManager; setHeaderActionMenu?: AppMountParameters['setHeaderActionMenu']; }): DiscoverServices => { const { usageCollection } = plugins; @@ -217,6 +221,7 @@ export const buildServices = memoize( noDataPage: plugins.noDataPage, observabilityAIAssistant: plugins.observabilityAIAssistant, profilesManager, + ebtContextManager, fieldsMetadata: plugins.fieldsMetadata, }; } diff --git a/src/plugins/discover/public/context_awareness/__mocks__/index.tsx b/src/plugins/discover/public/context_awareness/__mocks__/index.tsx index cd8ab77875afb..c0e3d981668cf 100644 --- a/src/plugins/discover/public/context_awareness/__mocks__/index.tsx +++ b/src/plugins/discover/public/context_awareness/__mocks__/index.tsx @@ -22,6 +22,7 @@ import { SolutionType, } from '../profiles'; import { ProfilesManager } from '../profiles_manager'; +import { DiscoverEBTContextManager } from '../../services/discover_ebt_context_manager'; import { createLogsContextServiceMock } from '@kbn/discover-utils/src/__mocks__'; export const createContextAwarenessMocks = ({ @@ -150,10 +151,12 @@ export const createContextAwarenessMocks = ({ documentProfileServiceMock.registerProvider(documentProfileProviderMock); } + const ebtContextManagerMock = new DiscoverEBTContextManager(); const profilesManagerMock = new ProfilesManager( rootProfileServiceMock, dataSourceProfileServiceMock, - documentProfileServiceMock + documentProfileServiceMock, + ebtContextManagerMock ); const profileProviderServices = createProfileProviderServicesMock(); @@ -169,6 +172,7 @@ export const createContextAwarenessMocks = ({ contextRecordMock2, profilesManagerMock, profileProviderServices, + ebtContextManagerMock, }; }; diff --git a/src/plugins/discover/public/context_awareness/profiles_manager.test.ts b/src/plugins/discover/public/context_awareness/profiles_manager.test.ts index 65349b6fc5308..87965edbe7488 100644 --- a/src/plugins/discover/public/context_awareness/profiles_manager.test.ts +++ b/src/plugins/discover/public/context_awareness/profiles_manager.test.ts @@ -21,6 +21,7 @@ describe('ProfilesManager', () => { beforeEach(() => { jest.clearAllMocks(); mocks = createContextAwarenessMocks(); + jest.spyOn(mocks.ebtContextManagerMock, 'updateProfilesContextWith'); }); it('should return default profiles', () => { @@ -60,6 +61,11 @@ describe('ProfilesManager', () => { mocks.dataSourceProfileProviderMock.profile, mocks.documentProfileProviderMock.profile, ]); + + expect(mocks.ebtContextManagerMock.updateProfilesContextWith).toHaveBeenCalledWith([ + 'root-profile', + 'data-source-profile', + ]); }); it('should expose profiles as an observable', async () => { diff --git a/src/plugins/discover/public/context_awareness/profiles_manager.ts b/src/plugins/discover/public/context_awareness/profiles_manager.ts index 8c24e425147f5..2c8b1c7d16cb0 100644 --- a/src/plugins/discover/public/context_awareness/profiles_manager.ts +++ b/src/plugins/discover/public/context_awareness/profiles_manager.ts @@ -25,6 +25,7 @@ import type { DocumentContext, } from './profiles'; import type { ContextWithProfileId } from './profile_service'; +import { DiscoverEBTContextManager } from '../services/discover_ebt_context_manager'; interface SerializedRootProfileParams { solutionNavId: RootProfileProviderParams['solutionNavId']; @@ -52,6 +53,7 @@ export interface GetProfilesOptions { export class ProfilesManager { private readonly rootContext$: BehaviorSubject>; private readonly dataSourceContext$: BehaviorSubject>; + private readonly ebtContextManager: DiscoverEBTContextManager; private prevRootProfileParams?: SerializedRootProfileParams; private prevDataSourceProfileParams?: SerializedDataSourceProfileParams; @@ -61,10 +63,12 @@ export class ProfilesManager { constructor( private readonly rootProfileService: RootProfileService, private readonly dataSourceProfileService: DataSourceProfileService, - private readonly documentProfileService: DocumentProfileService + private readonly documentProfileService: DocumentProfileService, + ebtContextManager: DiscoverEBTContextManager ) { this.rootContext$ = new BehaviorSubject(rootProfileService.defaultContext); this.dataSourceContext$ = new BehaviorSubject(dataSourceProfileService.defaultContext); + this.ebtContextManager = ebtContextManager; } /** @@ -130,6 +134,7 @@ export class ProfilesManager { return; } + this.trackActiveProfiles(this.rootContext$.getValue().profileId, context.profileId); this.dataSourceContext$.next(context); this.prevDataSourceProfileParams = serializedParams; } @@ -194,6 +199,15 @@ export class ProfilesManager { map(() => this.getProfiles(options)) ); } + + /** + * Tracks the active profiles in the EBT context + */ + private trackActiveProfiles(rootContextProfileId: string, dataSourceContextProfileId: string) { + const dscProfiles = [rootContextProfileId, dataSourceContextProfileId]; + + this.ebtContextManager.updateProfilesContextWith(dscProfiles); + } } const serializeRootProfileParams = ( diff --git a/src/plugins/discover/public/plugin.tsx b/src/plugins/discover/public/plugin.tsx index a4e94205be7f4..507d5dfad7875 100644 --- a/src/plugins/discover/public/plugin.tsx +++ b/src/plugins/discover/public/plugin.tsx @@ -60,6 +60,7 @@ import { RootProfileService } from './context_awareness/profiles/root_profile'; import { DataSourceProfileService } from './context_awareness/profiles/data_source_profile'; import { DocumentProfileService } from './context_awareness/profiles/document_profile'; import { ProfilesManager } from './context_awareness/profiles_manager'; +import { DiscoverEBTContextManager } from './services/discover_ebt_context_manager'; /** * Contains Discover, one of the oldest parts of Kibana @@ -149,6 +150,9 @@ export class DiscoverPlugin this.urlTracker = { setTrackedUrl, restorePreviousUrl, setTrackingEnabled }; this.stopUrlTracking = stopUrlTracker; + const ebtContextManager = new DiscoverEBTContextManager(); + ebtContextManager.initialize({ core }); + core.application.register({ id: PLUGIN_ID, title: 'Discover', @@ -173,6 +177,8 @@ export class DiscoverPlugin window.dispatchEvent(new HashChangeEvent('hashchange')); }); + ebtContextManager.enable(); + const services = buildServices({ core: coreStart, plugins: discoverStartPlugins, @@ -183,7 +189,11 @@ export class DiscoverPlugin history: this.historyService.getHistory(), scopedHistory: this.scopedHistory, urlTracker: this.urlTracker!, - profilesManager: await this.createProfilesManager({ plugins: discoverStartPlugins }), + profilesManager: await this.createProfilesManager({ + plugins: discoverStartPlugins, + ebtContextManager, + }), + ebtContextManager, setHeaderActionMenu: params.setHeaderActionMenu, }); @@ -216,6 +226,7 @@ export class DiscoverPlugin }); return () => { + ebtContextManager.disableAndReset(); unlistenParentHistory(); unmount(); appUnMounted(); @@ -285,7 +296,12 @@ export class DiscoverPlugin } const getDiscoverServicesInternal = () => { - return this.getDiscoverServices(core, plugins, this.createEmptyProfilesManager()); + return this.getDiscoverServices( + core, + plugins, + this.createEmptyProfilesManager(), + new DiscoverEBTContextManager() // it's not enabled outside of Discover + ); }; return { @@ -320,14 +336,21 @@ export class DiscoverPlugin return { rootProfileService, dataSourceProfileService, documentProfileService }; }); - private async createProfilesManager({ plugins }: { plugins: DiscoverStartPlugins }) { + private async createProfilesManager({ + plugins, + ebtContextManager, + }: { + plugins: DiscoverStartPlugins; + ebtContextManager: DiscoverEBTContextManager; + }) { const { rootProfileService, dataSourceProfileService, documentProfileService } = await this.createProfileServices({ plugins }); return new ProfilesManager( rootProfileService, dataSourceProfileService, - documentProfileService + documentProfileService, + ebtContextManager ); } @@ -335,14 +358,16 @@ export class DiscoverPlugin return new ProfilesManager( new RootProfileService(), new DataSourceProfileService(), - new DocumentProfileService() + new DocumentProfileService(), + new DiscoverEBTContextManager() // it's not enabled outside of Discover ); } private getDiscoverServices = ( core: CoreStart, plugins: DiscoverStartPlugins, - profilesManager: ProfilesManager + profilesManager: ProfilesManager, + ebtContextManager: DiscoverEBTContextManager ) => { return buildServices({ core, @@ -354,6 +379,7 @@ export class DiscoverPlugin history: this.historyService.getHistory(), urlTracker: this.urlTracker!, profilesManager, + ebtContextManager, }); }; @@ -368,8 +394,12 @@ export class DiscoverPlugin const getDiscoverServicesInternal = async () => { const [coreStart, deps] = await core.getStartServices(); - const profilesManager = await this.createProfilesManager({ plugins: deps }); - return this.getDiscoverServices(coreStart, deps, profilesManager); + const ebtContextManager = new DiscoverEBTContextManager(); // it's not enabled outside of Discover + const profilesManager = await this.createProfilesManager({ + plugins: deps, + ebtContextManager, + }); + return this.getDiscoverServices(coreStart, deps, profilesManager, ebtContextManager); }; plugins.embeddable.registerReactEmbeddableSavedObject({ diff --git a/src/plugins/discover/public/services/discover_ebt_context_manager.test.ts b/src/plugins/discover/public/services/discover_ebt_context_manager.test.ts new file mode 100644 index 0000000000000..3b2836325b671 --- /dev/null +++ b/src/plugins/discover/public/services/discover_ebt_context_manager.test.ts @@ -0,0 +1,95 @@ +/* + * 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", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +import { BehaviorSubject } from 'rxjs'; +import { coreMock } from '@kbn/core/public/mocks'; +import { DiscoverEBTContextManager } from './discover_ebt_context_manager'; + +const coreSetupMock = coreMock.createSetup(); + +describe('DiscoverEBTContextManager', () => { + let discoverEBTContextManager: DiscoverEBTContextManager; + + beforeEach(() => { + discoverEBTContextManager = new DiscoverEBTContextManager(); + }); + + describe('register', () => { + it('should register the context provider', () => { + discoverEBTContextManager.initialize({ core: coreSetupMock }); + + expect(coreSetupMock.analytics.registerContextProvider).toHaveBeenCalledWith({ + name: 'discover_context', + context$: expect.any(BehaviorSubject), + schema: { + discoverProfiles: { + type: 'array', + items: { + type: 'keyword', + _meta: { + description: 'List of active Discover context awareness profiles', + }, + }, + }, + }, + }); + }); + }); + + describe('updateProfilesWith', () => { + it('should update the profiles with the provided props', () => { + const dscProfiles = ['profile1', 'profile2']; + const dscProfiles2 = ['profile21', 'profile22']; + discoverEBTContextManager.initialize({ core: coreSetupMock }); + discoverEBTContextManager.enable(); + + discoverEBTContextManager.updateProfilesContextWith(dscProfiles); + expect(discoverEBTContextManager.getProfilesContext()).toBe(dscProfiles); + + discoverEBTContextManager.updateProfilesContextWith(dscProfiles2); + expect(discoverEBTContextManager.getProfilesContext()).toBe(dscProfiles2); + }); + + it('should not update the profiles if profile list did not change', () => { + const dscProfiles = ['profile1', 'profile2']; + const dscProfiles2 = ['profile1', 'profile2']; + discoverEBTContextManager.initialize({ core: coreSetupMock }); + discoverEBTContextManager.enable(); + + discoverEBTContextManager.updateProfilesContextWith(dscProfiles); + expect(discoverEBTContextManager.getProfilesContext()).toBe(dscProfiles); + + discoverEBTContextManager.updateProfilesContextWith(dscProfiles2); + expect(discoverEBTContextManager.getProfilesContext()).toBe(dscProfiles); + }); + + it('should not update the profiles if not enabled yet', () => { + const dscProfiles = ['profile1', 'profile2']; + discoverEBTContextManager.initialize({ core: coreSetupMock }); + + discoverEBTContextManager.updateProfilesContextWith(dscProfiles); + expect(discoverEBTContextManager.getProfilesContext()).toEqual([]); + }); + + it('should not update the profiles after resetting unless enabled again', () => { + const dscProfiles = ['profile1', 'profile2']; + discoverEBTContextManager.initialize({ core: coreSetupMock }); + discoverEBTContextManager.enable(); + discoverEBTContextManager.updateProfilesContextWith(dscProfiles); + expect(discoverEBTContextManager.getProfilesContext()).toBe(dscProfiles); + discoverEBTContextManager.disableAndReset(); + expect(discoverEBTContextManager.getProfilesContext()).toEqual([]); + discoverEBTContextManager.updateProfilesContextWith(dscProfiles); + expect(discoverEBTContextManager.getProfilesContext()).toEqual([]); + discoverEBTContextManager.enable(); + discoverEBTContextManager.updateProfilesContextWith(dscProfiles); + expect(discoverEBTContextManager.getProfilesContext()).toBe(dscProfiles); + }); + }); +}); diff --git a/src/plugins/discover/public/services/discover_ebt_context_manager.ts b/src/plugins/discover/public/services/discover_ebt_context_manager.ts new file mode 100644 index 0000000000000..12ea918c495d9 --- /dev/null +++ b/src/plugins/discover/public/services/discover_ebt_context_manager.ts @@ -0,0 +1,75 @@ +/* + * 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", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +import { BehaviorSubject } from 'rxjs'; +import { isEqual } from 'lodash'; +import type { CoreSetup } from '@kbn/core-lifecycle-browser'; + +export interface DiscoverEBTContextProps { + discoverProfiles: string[]; // Discover Context Awareness Profiles +} +export type DiscoverEBTContext = BehaviorSubject; + +export class DiscoverEBTContextManager { + private isEnabled: boolean = false; + private ebtContext$: DiscoverEBTContext | undefined; + + constructor() {} + + // https://docs.elastic.dev/telemetry/collection/event-based-telemetry + public initialize({ core }: { core: CoreSetup }) { + const context$ = new BehaviorSubject({ + discoverProfiles: [], + }); + + core.analytics.registerContextProvider({ + name: 'discover_context', + context$, + schema: { + discoverProfiles: { + type: 'array', + items: { + type: 'keyword', + _meta: { + description: 'List of active Discover context awareness profiles', + }, + }, + }, + // If we decide to extend EBT context with more properties, we can do it here + }, + }); + + this.ebtContext$ = context$; + } + + public enable() { + this.isEnabled = true; + } + + public updateProfilesContextWith(discoverProfiles: DiscoverEBTContextProps['discoverProfiles']) { + if ( + this.isEnabled && + this.ebtContext$ && + !isEqual(this.ebtContext$.getValue().discoverProfiles, discoverProfiles) + ) { + this.ebtContext$.next({ + discoverProfiles, + }); + } + } + + public getProfilesContext() { + return this.ebtContext$?.getValue()?.discoverProfiles; + } + + public disableAndReset() { + this.updateProfilesContextWith([]); + this.isEnabled = false; + } +} diff --git a/src/plugins/discover/tsconfig.json b/src/plugins/discover/tsconfig.json index fef4b38d59cd5..65b121f47d105 100644 --- a/src/plugins/discover/tsconfig.json +++ b/src/plugins/discover/tsconfig.json @@ -98,7 +98,8 @@ "@kbn/security-solution-common", "@kbn/router-utils", "@kbn/management-settings-ids", - "@kbn/logs-data-access-plugin" + "@kbn/logs-data-access-plugin", + "@kbn/core-lifecycle-browser" ], "exclude": [ "target/**/*" diff --git a/test/functional/apps/discover/context_awareness/_data_source_profile.ts b/test/functional/apps/discover/context_awareness/_data_source_profile.ts index 35e3552afa655..ecf4b2fb29c4c 100644 --- a/test/functional/apps/discover/context_awareness/_data_source_profile.ts +++ b/test/functional/apps/discover/context_awareness/_data_source_profile.ts @@ -12,16 +12,115 @@ import expect from '@kbn/expect'; import type { FtrProviderContext } from '../ftr_provider_context'; export default function ({ getService, getPageObjects }: FtrProviderContext) { - const { common, discover, unifiedFieldList } = getPageObjects([ + const { common, discover, unifiedFieldList, dashboard, header, timePicker } = getPageObjects([ 'common', 'discover', 'unifiedFieldList', + 'dashboard', + 'header', + 'timePicker', ]); const testSubjects = getService('testSubjects'); const dataViews = getService('dataViews'); const dataGrid = getService('dataGrid'); + const monacoEditor = getService('monacoEditor'); + const ebtUIHelper = getService('kibana_ebt_ui'); + const retry = getService('retry'); + const esArchiver = getService('esArchiver'); + const kibanaServer = getService('kibanaServer'); + const dashboardAddPanel = getService('dashboardAddPanel'); describe('data source profile', () => { + describe('telemetry', () => { + before(async () => { + await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional'); + await kibanaServer.importExport.load('test/functional/fixtures/kbn_archiver/discover'); + }); + + after(async () => { + await kibanaServer.importExport.unload('test/functional/fixtures/kbn_archiver/discover'); + }); + + it('should set EBT context for telemetry events with default profile', async () => { + await common.navigateToApp('discover'); + await discover.selectTextBaseLang(); + await discover.waitUntilSearchingHasFinished(); + await monacoEditor.setCodeEditorValue('from my-example-* | sort @timestamp desc'); + await ebtUIHelper.setOptIn(true); + await testSubjects.click('querySubmitButton'); + await discover.waitUntilSearchingHasFinished(); + + const events = await ebtUIHelper.getEvents(Number.MAX_SAFE_INTEGER, { + eventTypes: ['performance_metric'], + withTimeoutMs: 500, + }); + + expect(events[events.length - 1].context.discoverProfiles).to.eql([ + 'example-root-profile', + 'default-data-source-profile', + ]); + }); + + it('should set EBT context for telemetry events when example profile and reset', async () => { + await common.navigateToApp('discover'); + await discover.selectTextBaseLang(); + await discover.waitUntilSearchingHasFinished(); + await monacoEditor.setCodeEditorValue('from my-example-logs | sort @timestamp desc'); + await ebtUIHelper.setOptIn(true); + await testSubjects.click('querySubmitButton'); + await discover.waitUntilSearchingHasFinished(); + + const events = await ebtUIHelper.getEvents(Number.MAX_SAFE_INTEGER, { + eventTypes: ['performance_metric'], + withTimeoutMs: 500, + }); + + expect(events[events.length - 1].context.discoverProfiles).to.eql([ + 'example-root-profile', + 'example-data-source-profile', + ]); + + // should reset the profiles when navigating away from Discover + await testSubjects.click('logo'); + await retry.waitFor('home page to open', async () => { + return (await testSubjects.getVisibleText('euiBreadcrumb')) === 'Home'; + }); + await testSubjects.click('addSampleData'); + + await retry.try(async () => { + const eventsAfter = await ebtUIHelper.getEvents(Number.MAX_SAFE_INTEGER, { + eventTypes: ['click'], + withTimeoutMs: 500, + }); + + expect(eventsAfter[eventsAfter.length - 1].context.discoverProfiles).to.eql([]); + }); + }); + + it('should not set EBT context for embeddables', async () => { + await dashboard.navigateToApp(); + await dashboard.gotoDashboardLandingPage(); + await dashboard.clickNewDashboard(); + await timePicker.setDefaultAbsoluteRange(); + await ebtUIHelper.setOptIn(true); + await dashboardAddPanel.addSavedSearch('A Saved Search'); + await header.waitUntilLoadingHasFinished(); + await dashboard.waitForRenderComplete(); + const rows = await dataGrid.getDocTableRows(); + expect(rows.length).to.be.above(0); + await testSubjects.click('dashboardEditorMenuButton'); + + const events = await ebtUIHelper.getEvents(Number.MAX_SAFE_INTEGER, { + eventTypes: ['click'], + withTimeoutMs: 500, + }); + + expect( + events.every((event) => !(event.context.discoverProfiles as string[])?.length) + ).to.be(true); + }); + }); + describe('ES|QL mode', () => { describe('cell renderers', () => { it('should render custom @timestamp but not custom log.level', async () => { diff --git a/test/functional/apps/discover/context_awareness/config.ts b/test/functional/apps/discover/context_awareness/config.ts index b56fb52c10d13..9261cef450adb 100644 --- a/test/functional/apps/discover/context_awareness/config.ts +++ b/test/functional/apps/discover/context_awareness/config.ts @@ -8,6 +8,11 @@ */ import { FtrConfigProviderContext } from '@kbn/test'; +import path from 'path'; +import { + KibanaEBTUIProvider, + KibanaEBTServerProvider, +} from '../../../../analytics/services/kibana_ebt'; export default async function ({ readConfigFile }: FtrConfigProviderContext) { const functionalConfig = await readConfigFile(require.resolve('../../../config.base.js')); @@ -21,7 +26,16 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { serverArgs: [ ...baseConfig.kbnTestServer.serverArgs, '--discover.experimental.enabledProfiles=["example-root-profile","example-data-source-profile","example-document-profile"]', + `--plugin-path=${path.resolve( + __dirname, + '../../../../analytics/plugins/analytics_ftr_helpers' + )}`, ], }, + services: { + ...baseConfig.services, + kibana_ebt_server: KibanaEBTServerProvider, + kibana_ebt_ui: KibanaEBTUIProvider, + }, }; } diff --git a/test/functional/apps/discover/ftr_provider_context.d.ts b/test/functional/apps/discover/ftr_provider_context.d.ts index f2df0c30545ee..8914a16512702 100644 --- a/test/functional/apps/discover/ftr_provider_context.d.ts +++ b/test/functional/apps/discover/ftr_provider_context.d.ts @@ -9,12 +9,18 @@ import { GenericFtrProviderContext } from '@kbn/test'; import { commonFunctionalServices } from '@kbn/ftr-common-functional-services'; +import { + KibanaEBTUIProvider, + KibanaEBTServerProvider, +} from '../../../analytics/services/kibana_ebt'; import { services as functionalServces } from '../../services'; import { pageObjects } from '../../page_objects'; const services = { ...functionalServces, ...commonFunctionalServices, + kibana_ebt_server: KibanaEBTServerProvider, + kibana_ebt_ui: KibanaEBTUIProvider, }; export type FtrProviderContext = GenericFtrProviderContext;