mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[Discover] Add support for contextual awareness functional tests (#185905)
## Summary This PR adds functional test support for the Discover contextual awareness framework, and adds tests for the initial `getCellRenderers` extension point using example profiles. To support this, this PR introduces a new YAML setting called `discover.experimental.enabledProfiles` which can be used to selectively enable profiles both for functional testing and demoing WIP profiles that aren't yet ready for GA. Example usage: ```yml discover.experimental.enabledProfiles: ['example-root-profile', 'example-data-source-profile', 'example-document-profile'] ``` Flaky test runs: - Stateful x50: https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/6304 - Serverless Observability x50: https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/6305 - Serverless Search x50: https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/6306 - Serverless Security x50: https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/6307 Resolves #184699. ### Checklist - [ ] 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 - [ ] Any UI touched in this PR is usable by keyboard only (learn more about [keyboard accessibility](https://webaim.org/techniques/keyboard/)) - [ ] Any UI touched in this PR does not create any new axe failures (run axe in browser: [FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/), [Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US)) - [ ] If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker) - [ ] This renders correctly on smaller devices using a responsive layout. (You can test this [in your browser](https://www.browserstack.com/guide/responsive-testing-on-local-server)) - [ ] This was checked for [cross-browser compatibility](https://www.elastic.co/support/matrix#matrix_browsers) ### For maintainers - [ ] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)
This commit is contained in:
parent
06f773934a
commit
57891ff353
35 changed files with 1073 additions and 204 deletions
|
@ -127,6 +127,7 @@ enabled:
|
|||
- test/functional/apps/discover/group6/config.ts
|
||||
- test/functional/apps/discover/group7/config.ts
|
||||
- test/functional/apps/discover/group8/config.ts
|
||||
- test/functional/apps/discover/context_awareness/config.ts
|
||||
- test/functional/apps/getting_started/config.ts
|
||||
- test/functional/apps/home/config.ts
|
||||
- test/functional/apps/kibana_overview/config.ts
|
||||
|
@ -426,6 +427,7 @@ enabled:
|
|||
- x-pack/test_serverless/functional/test_suites/observability/config.ts
|
||||
- x-pack/test_serverless/functional/test_suites/observability/config.examples.ts
|
||||
- x-pack/test_serverless/functional/test_suites/observability/config.saved_objects_management.ts
|
||||
- x-pack/test_serverless/functional/test_suites/observability/config.context_awareness.ts
|
||||
- x-pack/test_serverless/functional/test_suites/observability/common_configs/config.group1.ts
|
||||
- x-pack/test_serverless/functional/test_suites/observability/common_configs/config.group2.ts
|
||||
- x-pack/test_serverless/functional/test_suites/observability/common_configs/config.group3.ts
|
||||
|
@ -438,6 +440,7 @@ enabled:
|
|||
- x-pack/test_serverless/functional/test_suites/search/config.examples.ts
|
||||
- x-pack/test_serverless/functional/test_suites/search/config.screenshots.ts
|
||||
- x-pack/test_serverless/functional/test_suites/search/config.saved_objects_management.ts
|
||||
- x-pack/test_serverless/functional/test_suites/search/config.context_awareness.ts
|
||||
- x-pack/test_serverless/functional/test_suites/search/common_configs/config.group1.ts
|
||||
- x-pack/test_serverless/functional/test_suites/search/common_configs/config.group2.ts
|
||||
- x-pack/test_serverless/functional/test_suites/search/common_configs/config.group3.ts
|
||||
|
@ -449,6 +452,7 @@ enabled:
|
|||
- x-pack/test_serverless/functional/test_suites/security/config.cloud_security_posture.basic.ts
|
||||
- x-pack/test_serverless/functional/test_suites/security/config.cloud_security_posture.essentials.ts
|
||||
- x-pack/test_serverless/functional/test_suites/security/config.saved_objects_management.ts
|
||||
- x-pack/test_serverless/functional/test_suites/security/config.context_awareness.ts
|
||||
- x-pack/test_serverless/functional/test_suites/security/common_configs/config.group1.ts
|
||||
- x-pack/test_serverless/functional/test_suites/security/common_configs/config.group2.ts
|
||||
- x-pack/test_serverless/functional/test_suites/security/common_configs/config.group3.ts
|
||||
|
|
|
@ -13,9 +13,10 @@ export const configSchema = schema.object({
|
|||
experimental: schema.maybe(
|
||||
schema.object({
|
||||
ruleFormV2Enabled: schema.maybe(schema.boolean({ defaultValue: false })),
|
||||
enabledProfiles: schema.maybe(schema.arrayOf(schema.string(), { defaultValue: [] })),
|
||||
})
|
||||
),
|
||||
});
|
||||
|
||||
export type ConfigSchema = TypeOf<typeof configSchema>;
|
||||
export type ExperimentalFeatures = ConfigSchema['experimental'];
|
||||
export type ExperimentalFeatures = NonNullable<ConfigSchema['experimental']>;
|
||||
|
|
|
@ -19,10 +19,12 @@ import {
|
|||
RootProfileService,
|
||||
SolutionType,
|
||||
} from '../profiles';
|
||||
import { createProfileProviderServices } from '../profiles/profile_provider_services';
|
||||
import { createProfileProviderServices } from '../profile_providers/profile_provider_services';
|
||||
import { ProfilesManager } from '../profiles_manager';
|
||||
|
||||
export const createContextAwarenessMocks = () => {
|
||||
export const createContextAwarenessMocks = ({
|
||||
shouldRegisterProviders = true,
|
||||
}: { shouldRegisterProviders?: boolean } = {}) => {
|
||||
const rootProfileProviderMock: RootProfileProvider = {
|
||||
profileId: 'root-profile',
|
||||
profile: {
|
||||
|
@ -92,15 +94,15 @@ export const createContextAwarenessMocks = () => {
|
|||
const records = getDataTableRecords(dataViewWithTimefieldMock);
|
||||
const contextRecordMock = records[0];
|
||||
const contextRecordMock2 = records[1];
|
||||
|
||||
const rootProfileServiceMock = new RootProfileService();
|
||||
rootProfileServiceMock.registerProvider(rootProfileProviderMock);
|
||||
|
||||
const dataSourceProfileServiceMock = new DataSourceProfileService();
|
||||
dataSourceProfileServiceMock.registerProvider(dataSourceProfileProviderMock);
|
||||
|
||||
const documentProfileServiceMock = new DocumentProfileService();
|
||||
documentProfileServiceMock.registerProvider(documentProfileProviderMock);
|
||||
|
||||
if (shouldRegisterProviders) {
|
||||
rootProfileServiceMock.registerProvider(rootProfileProviderMock);
|
||||
dataSourceProfileServiceMock.registerProvider(dataSourceProfileProviderMock);
|
||||
documentProfileServiceMock.registerProvider(documentProfileProviderMock);
|
||||
}
|
||||
|
||||
const profilesManagerMock = new ProfilesManager(
|
||||
rootProfileServiceMock,
|
||||
|
@ -114,6 +116,9 @@ export const createContextAwarenessMocks = () => {
|
|||
rootProfileProviderMock,
|
||||
dataSourceProfileProviderMock,
|
||||
documentProfileProviderMock,
|
||||
rootProfileServiceMock,
|
||||
dataSourceProfileServiceMock,
|
||||
documentProfileServiceMock,
|
||||
contextRecordMock,
|
||||
contextRecordMock2,
|
||||
profilesManagerMock,
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* 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 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 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export { exampleDataSourceProfileProvider } from './profile';
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* 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 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 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { EuiBadge } from '@elastic/eui';
|
||||
import type { DataTableRecord } from '@kbn/discover-utils';
|
||||
import { isOfAggregateQueryType } from '@kbn/es-query';
|
||||
import { getIndexPatternFromESQLQuery } from '@kbn/esql-utils';
|
||||
import { euiThemeVars } from '@kbn/ui-theme';
|
||||
import { capitalize } from 'lodash';
|
||||
import React from 'react';
|
||||
import { DataSourceType, isDataSourceType } from '../../../../common/data_sources';
|
||||
import { DataSourceCategory, DataSourceProfileProvider } from '../../profiles';
|
||||
|
||||
export const exampleDataSourceProfileProvider: DataSourceProfileProvider = {
|
||||
profileId: 'example-data-source-profile',
|
||||
profile: {
|
||||
getCellRenderers: (prev) => () => ({
|
||||
...prev(),
|
||||
'log.level': (props) => {
|
||||
const level = getFieldValue(props.row, 'log.level');
|
||||
|
||||
if (!level) {
|
||||
return (
|
||||
<span
|
||||
css={{ color: euiThemeVars.euiTextSubduedColor }}
|
||||
data-test-subj="exampleDataSourceProfileLogLevelEmpty"
|
||||
>
|
||||
(None)
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
const levelMap: Record<string, string> = {
|
||||
info: 'primary',
|
||||
debug: 'default',
|
||||
error: 'danger',
|
||||
};
|
||||
|
||||
return (
|
||||
<EuiBadge
|
||||
color={levelMap[level]}
|
||||
title={level}
|
||||
data-test-subj="exampleDataSourceProfileLogLevel"
|
||||
>
|
||||
{capitalize(level)}
|
||||
</EuiBadge>
|
||||
);
|
||||
},
|
||||
}),
|
||||
},
|
||||
resolve: (params) => {
|
||||
let indexPattern: string | undefined;
|
||||
|
||||
if (isDataSourceType(params.dataSource, DataSourceType.Esql)) {
|
||||
if (!isOfAggregateQueryType(params.query)) {
|
||||
return { isMatch: false };
|
||||
}
|
||||
|
||||
indexPattern = getIndexPatternFromESQLQuery(params.query.esql);
|
||||
} else if (isDataSourceType(params.dataSource, DataSourceType.DataView) && params.dataView) {
|
||||
indexPattern = params.dataView.getIndexPattern();
|
||||
}
|
||||
|
||||
if (indexPattern !== 'my-example-logs') {
|
||||
return { isMatch: false };
|
||||
}
|
||||
|
||||
return {
|
||||
isMatch: true,
|
||||
context: { category: DataSourceCategory.Logs },
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
const getFieldValue = (record: DataTableRecord, field: string) => {
|
||||
const value = record.flattened[field];
|
||||
return Array.isArray(value) ? value[0] : value;
|
||||
};
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* 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 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 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export { exampleDocumentProfileProvider } from './profile';
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* 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 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 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import type { DataTableRecord } from '@kbn/discover-utils';
|
||||
import { DocumentProfileProvider, DocumentType } from '../../profiles';
|
||||
|
||||
export const exampleDocumentProfileProvider: DocumentProfileProvider = {
|
||||
profileId: 'example-document-profile',
|
||||
profile: {},
|
||||
resolve: (params) => {
|
||||
if (getFieldValue(params.record, 'data_stream.type') !== 'logs') {
|
||||
return { isMatch: false };
|
||||
}
|
||||
|
||||
return {
|
||||
isMatch: true,
|
||||
context: {
|
||||
type: DocumentType.Log,
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
const getFieldValue = (record: DataTableRecord, field: string) => {
|
||||
const value = record.flattened[field];
|
||||
return Array.isArray(value) ? value[0] : value;
|
||||
};
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* 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 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 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export { exampleRootProfileProvider } from './profile';
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* 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 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 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { EuiBadge } from '@elastic/eui';
|
||||
import type { DataTableRecord } from '@kbn/discover-utils';
|
||||
import React from 'react';
|
||||
import { RootProfileProvider, SolutionType } from '../../profiles';
|
||||
|
||||
export const exampleRootProfileProvider: RootProfileProvider = {
|
||||
profileId: 'example-root-profile',
|
||||
profile: {
|
||||
getCellRenderers: (prev) => () => ({
|
||||
...prev(),
|
||||
'@timestamp': (props) => {
|
||||
const timestamp = getFieldValue(props.row, '@timestamp');
|
||||
|
||||
return (
|
||||
<EuiBadge color="hollow" title={timestamp} data-test-subj="exampleRootProfileTimestamp">
|
||||
{timestamp}
|
||||
</EuiBadge>
|
||||
);
|
||||
},
|
||||
}),
|
||||
},
|
||||
resolve: (params) => {
|
||||
if (params.solutionNavId != null) {
|
||||
return { isMatch: false };
|
||||
}
|
||||
|
||||
return { isMatch: true, context: { solutionType: SolutionType.Default } };
|
||||
},
|
||||
};
|
||||
|
||||
const getFieldValue = (record: DataTableRecord, field: string) => {
|
||||
const value = record.flattened[field];
|
||||
return Array.isArray(value) ? value[0] : value;
|
||||
};
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* 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 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 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export { registerProfileProviders } from './register_profile_providers';
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
import { DataTableRecord } from '@kbn/discover-utils';
|
||||
import { DocumentProfileProvider, DocumentType } from '../../profiles';
|
||||
import { ProfileProviderServices } from '../../profiles/profile_provider_services';
|
||||
import { ProfileProviderServices } from '../profile_provider_services';
|
||||
|
||||
export const createLogDocumentProfileProvider = (
|
||||
services: ProfileProviderServices
|
||||
|
|
|
@ -14,7 +14,7 @@ import {
|
|||
DataSourceProfileProvider,
|
||||
DataSourceProfileProviderParams,
|
||||
} from '../../profiles';
|
||||
import { ProfileProviderServices } from '../../profiles/profile_provider_services';
|
||||
import { ProfileProviderServices } from '../profile_provider_services';
|
||||
|
||||
export const createLogsDataSourceProfileProvider = (
|
||||
services: ProfileProviderServices
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* 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 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 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { createEsqlDataSource } from '../../../common/data_sources';
|
||||
import { createContextAwarenessMocks } from '../__mocks__';
|
||||
import { exampleDataSourceProfileProvider } from './example_data_source_profile';
|
||||
import { exampleDocumentProfileProvider } from './example_document_profile';
|
||||
import { exampleRootProfileProvider } from './example_root_pofile';
|
||||
import {
|
||||
registerEnabledProfileProviders,
|
||||
registerProfileProviders,
|
||||
} from './register_profile_providers';
|
||||
|
||||
describe('registerEnabledProfileProviders', () => {
|
||||
it('should register enabled profile providers', async () => {
|
||||
const { rootProfileServiceMock, rootProfileProviderMock } = createContextAwarenessMocks({
|
||||
shouldRegisterProviders: false,
|
||||
});
|
||||
registerEnabledProfileProviders({
|
||||
profileService: rootProfileServiceMock,
|
||||
availableProviders: [rootProfileProviderMock],
|
||||
enabledProfileIds: ['root-profile'],
|
||||
});
|
||||
const context = await rootProfileServiceMock.resolve({ solutionNavId: null });
|
||||
expect(rootProfileServiceMock.getProfile(context)).toBe(rootProfileProviderMock.profile);
|
||||
});
|
||||
|
||||
it('should not register disabled profile providers', async () => {
|
||||
const { rootProfileServiceMock, rootProfileProviderMock } = createContextAwarenessMocks({
|
||||
shouldRegisterProviders: false,
|
||||
});
|
||||
registerEnabledProfileProviders({
|
||||
profileService: rootProfileServiceMock,
|
||||
availableProviders: [rootProfileProviderMock],
|
||||
enabledProfileIds: [],
|
||||
});
|
||||
const context = await rootProfileServiceMock.resolve({ solutionNavId: null });
|
||||
expect(rootProfileServiceMock.getProfile(context)).not.toBe(rootProfileProviderMock.profile);
|
||||
});
|
||||
});
|
||||
|
||||
describe('registerProfileProviders', () => {
|
||||
it('should register enabled experimental profile providers', async () => {
|
||||
const { rootProfileServiceMock, dataSourceProfileServiceMock, documentProfileServiceMock } =
|
||||
createContextAwarenessMocks({
|
||||
shouldRegisterProviders: false,
|
||||
});
|
||||
registerProfileProviders({
|
||||
rootProfileService: rootProfileServiceMock,
|
||||
dataSourceProfileService: dataSourceProfileServiceMock,
|
||||
documentProfileService: documentProfileServiceMock,
|
||||
experimentalProfileIds: [
|
||||
exampleRootProfileProvider.profileId,
|
||||
exampleDataSourceProfileProvider.profileId,
|
||||
exampleDocumentProfileProvider.profileId,
|
||||
],
|
||||
});
|
||||
const rootContext = await rootProfileServiceMock.resolve({ solutionNavId: null });
|
||||
const dataSourceContext = await dataSourceProfileServiceMock.resolve({
|
||||
dataSource: createEsqlDataSource(),
|
||||
query: { esql: 'from my-example-logs' },
|
||||
});
|
||||
const documentContext = documentProfileServiceMock.resolve({
|
||||
record: {
|
||||
id: 'test',
|
||||
flattened: { 'data_stream.type': 'logs' },
|
||||
raw: {},
|
||||
},
|
||||
});
|
||||
expect(rootProfileServiceMock.getProfile(rootContext)).toBe(exampleRootProfileProvider.profile);
|
||||
expect(dataSourceProfileServiceMock.getProfile(dataSourceContext)).toBe(
|
||||
exampleDataSourceProfileProvider.profile
|
||||
);
|
||||
expect(documentProfileServiceMock.getProfile(documentContext)).toBe(
|
||||
exampleDocumentProfileProvider.profile
|
||||
);
|
||||
});
|
||||
|
||||
it('should not register disabled experimental profile providers', async () => {
|
||||
const { rootProfileServiceMock, dataSourceProfileServiceMock, documentProfileServiceMock } =
|
||||
createContextAwarenessMocks({
|
||||
shouldRegisterProviders: false,
|
||||
});
|
||||
registerProfileProviders({
|
||||
rootProfileService: rootProfileServiceMock,
|
||||
dataSourceProfileService: dataSourceProfileServiceMock,
|
||||
documentProfileService: documentProfileServiceMock,
|
||||
experimentalProfileIds: [],
|
||||
});
|
||||
const rootContext = await rootProfileServiceMock.resolve({ solutionNavId: null });
|
||||
const dataSourceContext = await dataSourceProfileServiceMock.resolve({
|
||||
dataSource: createEsqlDataSource(),
|
||||
query: { esql: 'from my-example-logs' },
|
||||
});
|
||||
const documentContext = documentProfileServiceMock.resolve({
|
||||
record: {
|
||||
id: 'test',
|
||||
flattened: { 'data_stream.type': 'logs' },
|
||||
raw: {},
|
||||
},
|
||||
});
|
||||
expect(rootProfileServiceMock.getProfile(rootContext)).not.toBe(
|
||||
exampleRootProfileProvider.profile
|
||||
);
|
||||
expect(dataSourceProfileServiceMock.getProfile(dataSourceContext)).not.toBe(
|
||||
exampleDataSourceProfileProvider.profile
|
||||
);
|
||||
expect(documentProfileServiceMock.getProfile(documentContext)).not.toBe(
|
||||
exampleDocumentProfileProvider.profile
|
||||
);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* 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 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 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { uniq } from 'lodash';
|
||||
import type {
|
||||
DataSourceProfileService,
|
||||
DocumentProfileService,
|
||||
RootProfileService,
|
||||
} from '../profiles';
|
||||
import type { BaseProfileProvider, BaseProfileService } from '../profile_service';
|
||||
import { exampleDataSourceProfileProvider } from './example_data_source_profile';
|
||||
import { exampleDocumentProfileProvider } from './example_document_profile';
|
||||
import { exampleRootProfileProvider } from './example_root_pofile';
|
||||
import { createLogsDataSourceProfileProvider } from './logs_data_source_profile';
|
||||
import { createLogDocumentProfileProvider } from './log_document_profile';
|
||||
import { createProfileProviderServices } from './profile_provider_services';
|
||||
|
||||
export const registerProfileProviders = ({
|
||||
rootProfileService,
|
||||
dataSourceProfileService,
|
||||
documentProfileService,
|
||||
experimentalProfileIds,
|
||||
}: {
|
||||
rootProfileService: RootProfileService;
|
||||
dataSourceProfileService: DataSourceProfileService;
|
||||
documentProfileService: DocumentProfileService;
|
||||
experimentalProfileIds: string[];
|
||||
}) => {
|
||||
const providerServices = createProfileProviderServices();
|
||||
const logsDataSourceProfileProvider = createLogsDataSourceProfileProvider(providerServices);
|
||||
const logsDocumentProfileProvider = createLogDocumentProfileProvider(providerServices);
|
||||
const rootProfileProviders = [exampleRootProfileProvider];
|
||||
const dataSourceProfileProviders = [
|
||||
exampleDataSourceProfileProvider,
|
||||
logsDataSourceProfileProvider,
|
||||
];
|
||||
const documentProfileProviders = [exampleDocumentProfileProvider, logsDocumentProfileProvider];
|
||||
const enabledProfileIds = uniq([
|
||||
logsDataSourceProfileProvider.profileId,
|
||||
logsDocumentProfileProvider.profileId,
|
||||
...experimentalProfileIds,
|
||||
]);
|
||||
|
||||
registerEnabledProfileProviders({
|
||||
profileService: rootProfileService,
|
||||
availableProviders: rootProfileProviders,
|
||||
enabledProfileIds,
|
||||
});
|
||||
|
||||
registerEnabledProfileProviders({
|
||||
profileService: dataSourceProfileService,
|
||||
availableProviders: dataSourceProfileProviders,
|
||||
enabledProfileIds,
|
||||
});
|
||||
|
||||
registerEnabledProfileProviders({
|
||||
profileService: documentProfileService,
|
||||
availableProviders: documentProfileProviders,
|
||||
enabledProfileIds,
|
||||
});
|
||||
};
|
||||
|
||||
export const registerEnabledProfileProviders = <
|
||||
TProvider extends BaseProfileProvider<{}>,
|
||||
TService extends BaseProfileService<TProvider, {}>
|
||||
>({
|
||||
profileService,
|
||||
availableProviders,
|
||||
enabledProfileIds,
|
||||
}: {
|
||||
profileService: TService;
|
||||
availableProviders: TProvider[];
|
||||
enabledProfileIds: string[];
|
||||
}) => {
|
||||
for (const profile of availableProviders) {
|
||||
if (enabledProfileIds.includes(profile.profileId)) {
|
||||
profileService.registerProvider(profile);
|
||||
}
|
||||
}
|
||||
};
|
|
@ -15,38 +15,33 @@ export type ResolveProfileResult<TContext> =
|
|||
| { isMatch: true; context: TContext }
|
||||
| { isMatch: false };
|
||||
|
||||
export type ProfileProviderMode = 'sync' | 'async';
|
||||
export type ContextWithProfileId<TContext> = TContext & { profileId: string };
|
||||
|
||||
export interface ProfileProvider<
|
||||
TProfile extends PartialProfile,
|
||||
TParams,
|
||||
TContext,
|
||||
TMode extends ProfileProviderMode
|
||||
> {
|
||||
export interface BaseProfileProvider<TProfile extends PartialProfile> {
|
||||
profileId: string;
|
||||
profile: ComposableProfile<TProfile>;
|
||||
resolve: (
|
||||
params: TParams
|
||||
) => TMode extends 'sync'
|
||||
? ResolveProfileResult<TContext>
|
||||
: ResolveProfileResult<TContext> | Promise<ResolveProfileResult<TContext>>;
|
||||
}
|
||||
|
||||
export type ContextWithProfileId<TContext> = TContext & { profileId: string };
|
||||
export interface ProfileProvider<TProfile extends PartialProfile, TParams, TContext>
|
||||
extends BaseProfileProvider<TProfile> {
|
||||
resolve: (params: TParams) => ResolveProfileResult<TContext>;
|
||||
}
|
||||
|
||||
export interface AsyncProfileProvider<TProfile extends PartialProfile, TParams, TContext>
|
||||
extends BaseProfileProvider<TProfile> {
|
||||
resolve: (
|
||||
params: TParams
|
||||
) => ResolveProfileResult<TContext> | Promise<ResolveProfileResult<TContext>>;
|
||||
}
|
||||
|
||||
const EMPTY_PROFILE = {};
|
||||
|
||||
abstract class BaseProfileService<
|
||||
TProfile extends PartialProfile,
|
||||
TParams,
|
||||
TContext,
|
||||
TMode extends ProfileProviderMode
|
||||
> {
|
||||
protected readonly providers: Array<ProfileProvider<TProfile, TParams, TContext, TMode>> = [];
|
||||
export abstract class BaseProfileService<TProvider extends BaseProfileProvider<{}>, TContext> {
|
||||
protected readonly providers: TProvider[] = [];
|
||||
|
||||
protected constructor(public readonly defaultContext: ContextWithProfileId<TContext>) {}
|
||||
|
||||
public registerProvider(provider: ProfileProvider<TProfile, TParams, TContext, TMode>) {
|
||||
public registerProvider(provider: TProvider) {
|
||||
this.providers.push(provider);
|
||||
}
|
||||
|
||||
|
@ -54,19 +49,13 @@ abstract class BaseProfileService<
|
|||
const provider = this.providers.find((current) => current.profileId === context.profileId);
|
||||
return provider?.profile ?? EMPTY_PROFILE;
|
||||
}
|
||||
|
||||
public abstract resolve(
|
||||
params: TParams
|
||||
): TMode extends 'sync'
|
||||
? ContextWithProfileId<TContext>
|
||||
: Promise<ContextWithProfileId<TContext>>;
|
||||
}
|
||||
|
||||
export class ProfileService<
|
||||
TProfile extends PartialProfile,
|
||||
TParams,
|
||||
TContext
|
||||
> extends BaseProfileService<TProfile, TParams, TContext, 'sync'> {
|
||||
> extends BaseProfileService<ProfileProvider<TProfile, TParams, TContext>, TContext> {
|
||||
public resolve(params: TParams) {
|
||||
for (const provider of this.providers) {
|
||||
const result = provider.resolve(params);
|
||||
|
@ -87,7 +76,7 @@ export class AsyncProfileService<
|
|||
TProfile extends PartialProfile,
|
||||
TParams,
|
||||
TContext
|
||||
> extends BaseProfileService<TProfile, TParams, TContext, 'async'> {
|
||||
> extends BaseProfileService<AsyncProfileProvider<TProfile, TParams, TContext>, TContext> {
|
||||
public async resolve(params: TParams) {
|
||||
for (const provider of this.providers) {
|
||||
const result = await provider.resolve(params);
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
import type { DataView } from '@kbn/data-views-plugin/common';
|
||||
import type { AggregateQuery, Query } from '@kbn/es-query';
|
||||
import type { DiscoverDataSource } from '../../../common/data_sources';
|
||||
import { AsyncProfileService } from '../profile_service';
|
||||
import { AsyncProfileProvider, AsyncProfileService } from '../profile_service';
|
||||
import { Profile } from '../types';
|
||||
|
||||
export enum DataSourceCategory {
|
||||
|
@ -17,6 +17,8 @@ export enum DataSourceCategory {
|
|||
Default = 'default',
|
||||
}
|
||||
|
||||
export type DataSourceProfile = Profile;
|
||||
|
||||
export interface DataSourceProfileProviderParams {
|
||||
dataSource?: DiscoverDataSource;
|
||||
dataView?: DataView;
|
||||
|
@ -27,7 +29,11 @@ export interface DataSourceContext {
|
|||
category: DataSourceCategory;
|
||||
}
|
||||
|
||||
export type DataSourceProfile = Profile;
|
||||
export type DataSourceProfileProvider = AsyncProfileProvider<
|
||||
DataSourceProfile,
|
||||
DataSourceProfileProviderParams,
|
||||
DataSourceContext
|
||||
>;
|
||||
|
||||
export class DataSourceProfileService extends AsyncProfileService<
|
||||
DataSourceProfile,
|
||||
|
@ -41,5 +47,3 @@ export class DataSourceProfileService extends AsyncProfileService<
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
export type DataSourceProfileProvider = Parameters<DataSourceProfileService['registerProvider']>[0];
|
||||
|
|
|
@ -8,13 +8,15 @@
|
|||
|
||||
import type { DataTableRecord } from '@kbn/discover-utils';
|
||||
import type { Profile } from '../types';
|
||||
import { ProfileService } from '../profile_service';
|
||||
import { ProfileProvider, ProfileService } from '../profile_service';
|
||||
|
||||
export enum DocumentType {
|
||||
Log = 'log',
|
||||
Default = 'default',
|
||||
}
|
||||
|
||||
export type DocumentProfile = Omit<Profile, 'getCellRenderers'>;
|
||||
|
||||
export interface DocumentProfileProviderParams {
|
||||
record: DataTableRecord;
|
||||
}
|
||||
|
@ -23,7 +25,11 @@ export interface DocumentContext {
|
|||
type: DocumentType;
|
||||
}
|
||||
|
||||
export type DocumentProfile = Omit<Profile, 'getCellRenderers'>;
|
||||
export type DocumentProfileProvider = ProfileProvider<
|
||||
DocumentProfile,
|
||||
DocumentProfileProviderParams,
|
||||
DocumentContext
|
||||
>;
|
||||
|
||||
export class DocumentProfileService extends ProfileService<
|
||||
DocumentProfile,
|
||||
|
@ -37,5 +43,3 @@ export class DocumentProfileService extends ProfileService<
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
export type DocumentProfileProvider = Parameters<DocumentProfileService['registerProvider']>[0];
|
||||
|
|
|
@ -1,123 +0,0 @@
|
|||
/*
|
||||
* 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 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 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { EuiBadge } from '@elastic/eui';
|
||||
import {
|
||||
DataTableRecord,
|
||||
getMessageFieldWithFallbacks,
|
||||
LogDocumentOverview,
|
||||
} from '@kbn/discover-utils';
|
||||
import { isOfAggregateQueryType } from '@kbn/es-query';
|
||||
import { getIndexPatternFromESQLQuery } from '@kbn/esql-utils';
|
||||
import { euiThemeVars } from '@kbn/ui-theme';
|
||||
import { capitalize } from 'lodash';
|
||||
import React from 'react';
|
||||
import { DataSourceType, isDataSourceType } from '../../../common/data_sources';
|
||||
import { DataSourceCategory, DataSourceProfileProvider } from './data_source_profile';
|
||||
import { DocumentProfileProvider, DocumentType } from './document_profile';
|
||||
import { RootProfileProvider, SolutionType } from './root_profile';
|
||||
|
||||
export const o11yRootProfileProvider: RootProfileProvider = {
|
||||
profileId: 'o11y-root-profile',
|
||||
profile: {},
|
||||
resolve: (params) => {
|
||||
if (params.solutionNavId === 'oblt') {
|
||||
return {
|
||||
isMatch: true,
|
||||
context: {
|
||||
solutionType: SolutionType.Observability,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return { isMatch: false };
|
||||
},
|
||||
};
|
||||
|
||||
export const logsDataSourceProfileProvider: DataSourceProfileProvider = {
|
||||
profileId: 'logs-data-source-profile',
|
||||
profile: {
|
||||
getCellRenderers: (prev) => () => ({
|
||||
...prev(),
|
||||
'@timestamp': (props) => {
|
||||
const timestamp = getFieldValue(props.row, '@timestamp');
|
||||
return (
|
||||
<EuiBadge color="hollow" title={timestamp}>
|
||||
{timestamp}
|
||||
</EuiBadge>
|
||||
);
|
||||
},
|
||||
'log.level': (props) => {
|
||||
const level = getFieldValue(props.row, 'log.level');
|
||||
if (!level) {
|
||||
return <span css={{ color: euiThemeVars.euiTextSubduedColor }}>(None)</span>;
|
||||
}
|
||||
const levelMap: Record<string, string> = {
|
||||
info: 'primary',
|
||||
debug: 'default',
|
||||
error: 'danger',
|
||||
};
|
||||
return (
|
||||
<EuiBadge color={levelMap[level]} title={level}>
|
||||
{capitalize(level)}
|
||||
</EuiBadge>
|
||||
);
|
||||
},
|
||||
message: (props) => {
|
||||
const { value } = getMessageFieldWithFallbacks(
|
||||
props.row.flattened as unknown as LogDocumentOverview
|
||||
);
|
||||
return value || <span css={{ color: euiThemeVars.euiTextSubduedColor }}>(None)</span>;
|
||||
},
|
||||
}),
|
||||
},
|
||||
resolve: (params) => {
|
||||
let indices: string[] = [];
|
||||
|
||||
if (isDataSourceType(params.dataSource, DataSourceType.Esql)) {
|
||||
if (!isOfAggregateQueryType(params.query)) {
|
||||
return { isMatch: false };
|
||||
}
|
||||
|
||||
indices = getIndexPatternFromESQLQuery(params.query.esql).split(',');
|
||||
} else if (isDataSourceType(params.dataSource, DataSourceType.DataView) && params.dataView) {
|
||||
indices = params.dataView.getIndexPattern().split(',');
|
||||
}
|
||||
|
||||
if (indices.every((index) => index.startsWith('logs-'))) {
|
||||
return {
|
||||
isMatch: true,
|
||||
context: { category: DataSourceCategory.Logs },
|
||||
};
|
||||
}
|
||||
|
||||
return { isMatch: false };
|
||||
},
|
||||
};
|
||||
|
||||
export const logDocumentProfileProvider: DocumentProfileProvider = {
|
||||
profileId: 'log-document-profile',
|
||||
profile: {},
|
||||
resolve: (params) => {
|
||||
if (getFieldValue(params.record, 'data_stream.type') === 'logs') {
|
||||
return {
|
||||
isMatch: true,
|
||||
context: {
|
||||
type: DocumentType.Log,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return { isMatch: false };
|
||||
},
|
||||
};
|
||||
|
||||
const getFieldValue = (record: DataTableRecord, field: string) => {
|
||||
const value = record.flattened[field];
|
||||
return Array.isArray(value) ? value[0] : value;
|
||||
};
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
import type { Profile } from '../types';
|
||||
import { AsyncProfileService } from '../profile_service';
|
||||
import { AsyncProfileProvider, AsyncProfileService } from '../profile_service';
|
||||
|
||||
export enum SolutionType {
|
||||
Observability = 'oblt',
|
||||
|
@ -16,6 +16,8 @@ export enum SolutionType {
|
|||
Default = 'default',
|
||||
}
|
||||
|
||||
export type RootProfile = Profile;
|
||||
|
||||
export interface RootProfileProviderParams {
|
||||
solutionNavId?: string | null;
|
||||
}
|
||||
|
@ -24,7 +26,11 @@ export interface RootContext {
|
|||
solutionType: SolutionType;
|
||||
}
|
||||
|
||||
export type RootProfile = Profile;
|
||||
export type RootProfileProvider = AsyncProfileProvider<
|
||||
RootProfile,
|
||||
RootProfileProviderParams,
|
||||
RootContext
|
||||
>;
|
||||
|
||||
export class RootProfileService extends AsyncProfileService<
|
||||
RootProfile,
|
||||
|
@ -38,5 +44,3 @@ export class RootProfileService extends AsyncProfileService<
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
export type RootProfileProvider = Parameters<RootProfileService['registerProvider']>[0];
|
||||
|
|
|
@ -21,6 +21,7 @@ import { DEFAULT_APP_CATEGORIES } from '@kbn/core/public';
|
|||
import { ENABLE_ESQL } from '@kbn/esql-utils';
|
||||
import { setStateToKbnUrl } from '@kbn/kibana-utils-plugin/public';
|
||||
import { TRUNCATE_MAX_HEIGHT } from '@kbn/discover-utils';
|
||||
import { once } from 'lodash';
|
||||
import { PLUGIN_ID } from '../common';
|
||||
import { registerFeature } from './register_feature';
|
||||
import { buildServices, UrlTracker } from './build_services';
|
||||
|
@ -56,10 +57,7 @@ import {
|
|||
ProfilesManager,
|
||||
RootProfileService,
|
||||
} from './context_awareness';
|
||||
import { createProfileProviderServices } from './context_awareness/profiles/profile_provider_services';
|
||||
import { DiscoverSetup, DiscoverSetupPlugins, DiscoverStart, DiscoverStartPlugins } from './types';
|
||||
import { createLogsDataSourceProfileProvider } from './context_awareness/profile_providers/logs_data_source_profile';
|
||||
import { createLogDocumentProfileProvider } from './context_awareness/profile_providers/log_document_profile';
|
||||
|
||||
/**
|
||||
* Contains Discover, one of the oldest parts of Kibana
|
||||
|
@ -68,16 +66,11 @@ import { createLogDocumentProfileProvider } from './context_awareness/profile_pr
|
|||
export class DiscoverPlugin
|
||||
implements Plugin<DiscoverSetup, DiscoverStart, DiscoverSetupPlugins, DiscoverStartPlugins>
|
||||
{
|
||||
private readonly rootProfileService = new RootProfileService();
|
||||
private readonly dataSourceProfileService = new DataSourceProfileService();
|
||||
private readonly documentProfileService = new DocumentProfileService();
|
||||
private readonly appStateUpdater = new BehaviorSubject<AppUpdater>(() => ({}));
|
||||
private readonly historyService = new HistoryService();
|
||||
private readonly inlineTopNav: Map<string | null, DiscoverCustomizationContext['inlineTopNav']> =
|
||||
new Map([[null, defaultCustomizationContext.inlineTopNav]]);
|
||||
private readonly experimentalFeatures: ExperimentalFeatures = {
|
||||
ruleFormV2Enabled: false,
|
||||
};
|
||||
private readonly experimentalFeatures: ExperimentalFeatures;
|
||||
|
||||
private scopedHistory?: ScopedHistory<unknown>;
|
||||
private urlTracker?: UrlTracker;
|
||||
|
@ -87,8 +80,12 @@ export class DiscoverPlugin
|
|||
private singleDocLocator?: DiscoverSingleDocLocator;
|
||||
|
||||
constructor(private readonly initializerContext: PluginInitializerContext<ConfigSchema>) {
|
||||
this.experimentalFeatures =
|
||||
initializerContext.config.get().experimental ?? this.experimentalFeatures;
|
||||
const experimental = this.initializerContext.config.get().experimental;
|
||||
|
||||
this.experimentalFeatures = {
|
||||
ruleFormV2Enabled: experimental?.ruleFormV2Enabled ?? false,
|
||||
enabledProfiles: experimental?.enabledProfiles ?? [],
|
||||
};
|
||||
}
|
||||
|
||||
setup(
|
||||
|
@ -184,7 +181,7 @@ export class DiscoverPlugin
|
|||
history: this.historyService.getHistory(),
|
||||
scopedHistory: this.scopedHistory,
|
||||
urlTracker: this.urlTracker!,
|
||||
profilesManager: this.createProfilesManager(),
|
||||
profilesManager: await this.createProfilesManager(),
|
||||
setHeaderActionMenu: params.setHeaderActionMenu,
|
||||
});
|
||||
|
||||
|
@ -267,8 +264,6 @@ export class DiscoverPlugin
|
|||
}
|
||||
|
||||
start(core: CoreStart, plugins: DiscoverStartPlugins): DiscoverStart {
|
||||
this.registerProfiles();
|
||||
|
||||
const viewSavedSearchAction = new ViewSavedSearchAction(core.application, this.locator!);
|
||||
|
||||
plugins.uiActions.addTriggerAction('CONTEXT_MENU_TRIGGER', viewSavedSearchAction);
|
||||
|
@ -304,22 +299,31 @@ export class DiscoverPlugin
|
|||
}
|
||||
}
|
||||
|
||||
private registerProfiles() {
|
||||
const providerServices = createProfileProviderServices();
|
||||
private createProfileServices = once(async () => {
|
||||
const { registerProfileProviders } = await import('./context_awareness/profile_providers');
|
||||
const rootProfileService = new RootProfileService();
|
||||
const dataSourceProfileService = new DataSourceProfileService();
|
||||
const documentProfileService = new DocumentProfileService();
|
||||
const experimentalProfileIds = this.experimentalFeatures.enabledProfiles ?? [];
|
||||
|
||||
this.dataSourceProfileService.registerProvider(
|
||||
createLogsDataSourceProfileProvider(providerServices)
|
||||
);
|
||||
this.documentProfileService.registerProvider(
|
||||
createLogDocumentProfileProvider(providerServices)
|
||||
);
|
||||
}
|
||||
registerProfileProviders({
|
||||
rootProfileService,
|
||||
dataSourceProfileService,
|
||||
documentProfileService,
|
||||
experimentalProfileIds,
|
||||
});
|
||||
|
||||
return { rootProfileService, dataSourceProfileService, documentProfileService };
|
||||
});
|
||||
|
||||
private async createProfilesManager() {
|
||||
const { rootProfileService, dataSourceProfileService, documentProfileService } =
|
||||
await this.createProfileServices();
|
||||
|
||||
private createProfilesManager() {
|
||||
return new ProfilesManager(
|
||||
this.rootProfileService,
|
||||
this.dataSourceProfileService,
|
||||
this.documentProfileService
|
||||
rootProfileService,
|
||||
dataSourceProfileService,
|
||||
documentProfileService
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -334,7 +338,7 @@ export class DiscoverPlugin
|
|||
private getDiscoverServices = (
|
||||
core: CoreStart,
|
||||
plugins: DiscoverStartPlugins,
|
||||
profilesManager = this.createProfilesManager()
|
||||
profilesManager: ProfilesManager
|
||||
) => {
|
||||
return buildServices({
|
||||
core,
|
||||
|
@ -360,7 +364,8 @@ export class DiscoverPlugin
|
|||
|
||||
const getDiscoverServicesInternal = async () => {
|
||||
const [coreStart, deps] = await core.getStartServices();
|
||||
return this.getDiscoverServices(coreStart, deps);
|
||||
const profilesManager = await this.createProfilesManager();
|
||||
return this.getDiscoverServices(coreStart, deps, profilesManager);
|
||||
};
|
||||
|
||||
const factory = new SearchEmbeddableFactory(getStartServices, getDiscoverServicesInternal);
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* 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 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 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import kbnRison from '@kbn/rison';
|
||||
import expect from '@kbn/expect';
|
||||
import type { FtrProviderContext } from '../ftr_provider_context';
|
||||
|
||||
export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
||||
const PageObjects = getPageObjects(['common', 'timePicker', 'discover', 'unifiedFieldList']);
|
||||
const testSubjects = getService('testSubjects');
|
||||
const dataViews = getService('dataViews');
|
||||
|
||||
describe('data source profile', () => {
|
||||
describe('ES|QL mode', () => {
|
||||
describe('cell renderers', () => {
|
||||
it('should render custom @timestamp but not custom log.level', async () => {
|
||||
const state = kbnRison.encode({
|
||||
dataSource: { type: 'esql' },
|
||||
query: { esql: 'from my-example-* | sort @timestamp desc' },
|
||||
});
|
||||
await PageObjects.common.navigateToApp('discover', {
|
||||
hash: `/?_a=${state}`,
|
||||
});
|
||||
await PageObjects.discover.waitUntilSearchingHasFinished();
|
||||
await PageObjects.unifiedFieldList.clickFieldListItemAdd('@timestamp');
|
||||
await PageObjects.unifiedFieldList.clickFieldListItemAdd('log.level');
|
||||
const timestamps = await testSubjects.findAll('exampleRootProfileTimestamp');
|
||||
expect(timestamps).to.have.length(6);
|
||||
expect(await timestamps[0].getVisibleText()).to.be('2024-06-10T16:30:00.000Z');
|
||||
expect(await timestamps[5].getVisibleText()).to.be('2024-06-10T14:00:00.000Z');
|
||||
const logLevels = await testSubjects.findAll('exampleDataSourceProfileLogLevel', 2500);
|
||||
expect(logLevels).to.have.length(0);
|
||||
});
|
||||
|
||||
it('should render custom @timestamp and custom log.level', async () => {
|
||||
const state = kbnRison.encode({
|
||||
dataSource: { type: 'esql' },
|
||||
query: { esql: 'from my-example-logs | sort @timestamp desc' },
|
||||
});
|
||||
await PageObjects.common.navigateToApp('discover', {
|
||||
hash: `/?_a=${state}`,
|
||||
});
|
||||
await PageObjects.discover.waitUntilSearchingHasFinished();
|
||||
await PageObjects.unifiedFieldList.clickFieldListItemAdd('@timestamp');
|
||||
await PageObjects.unifiedFieldList.clickFieldListItemAdd('log.level');
|
||||
const timestamps = await testSubjects.findAll('exampleRootProfileTimestamp');
|
||||
expect(timestamps).to.have.length(3);
|
||||
expect(await timestamps[0].getVisibleText()).to.be('2024-06-10T16:00:00.000Z');
|
||||
expect(await timestamps[2].getVisibleText()).to.be('2024-06-10T14:00:00.000Z');
|
||||
const logLevels = await testSubjects.findAll('exampleDataSourceProfileLogLevel');
|
||||
expect(logLevels).to.have.length(3);
|
||||
expect(await logLevels[0].getVisibleText()).to.be('Debug');
|
||||
expect(await logLevels[2].getVisibleText()).to.be('Info');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('data view mode', () => {
|
||||
describe('cell renderers', () => {
|
||||
it('should render custom @timestamp but not custom log.level', async () => {
|
||||
await PageObjects.common.navigateToApp('discover');
|
||||
await dataViews.switchTo('my-example-*');
|
||||
await PageObjects.discover.waitUntilSearchingHasFinished();
|
||||
await PageObjects.unifiedFieldList.clickFieldListItemAdd('@timestamp');
|
||||
await PageObjects.unifiedFieldList.clickFieldListItemAdd('log.level');
|
||||
const timestamps = await testSubjects.findAll('exampleRootProfileTimestamp');
|
||||
expect(timestamps).to.have.length(6);
|
||||
expect(await timestamps[0].getVisibleText()).to.be('2024-06-10T16:30:00.000Z');
|
||||
expect(await timestamps[5].getVisibleText()).to.be('2024-06-10T14:00:00.000Z');
|
||||
const logLevels = await testSubjects.findAll('exampleDataSourceProfileLogLevel', 2500);
|
||||
expect(logLevels).to.have.length(0);
|
||||
});
|
||||
|
||||
it('should render custom @timestamp and custom log.level', async () => {
|
||||
await PageObjects.common.navigateToApp('discover');
|
||||
await dataViews.switchTo('my-example-logs');
|
||||
await PageObjects.discover.waitUntilSearchingHasFinished();
|
||||
await PageObjects.unifiedFieldList.clickFieldListItemAdd('@timestamp');
|
||||
await PageObjects.unifiedFieldList.clickFieldListItemAdd('log.level');
|
||||
const timestamps = await testSubjects.findAll('exampleRootProfileTimestamp');
|
||||
expect(timestamps).to.have.length(3);
|
||||
expect(await timestamps[0].getVisibleText()).to.be('2024-06-10T16:00:00.000Z');
|
||||
expect(await timestamps[2].getVisibleText()).to.be('2024-06-10T14:00:00.000Z');
|
||||
const logLevels = await testSubjects.findAll('exampleDataSourceProfileLogLevel');
|
||||
expect(logLevels).to.have.length(3);
|
||||
expect(await logLevels[0].getVisibleText()).to.be('Debug');
|
||||
expect(await logLevels[2].getVisibleText()).to.be('Info');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* 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 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 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import kbnRison from '@kbn/rison';
|
||||
import expect from '@kbn/expect';
|
||||
import type { FtrProviderContext } from '../ftr_provider_context';
|
||||
|
||||
export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
||||
const PageObjects = getPageObjects(['common', 'timePicker', 'discover']);
|
||||
const testSubjects = getService('testSubjects');
|
||||
const dataViews = getService('dataViews');
|
||||
|
||||
describe('root profile', () => {
|
||||
describe('ES|QL mode', () => {
|
||||
describe('cell renderers', () => {
|
||||
it('should render custom @timestamp', async () => {
|
||||
const state = kbnRison.encode({
|
||||
dataSource: { type: 'esql' },
|
||||
query: { esql: 'from my-example-* | sort @timestamp desc' },
|
||||
});
|
||||
await PageObjects.common.navigateToApp('discover', {
|
||||
hash: `/?_a=${state}`,
|
||||
});
|
||||
await PageObjects.discover.waitUntilSearchingHasFinished();
|
||||
const timestamps = await testSubjects.findAll('exampleRootProfileTimestamp');
|
||||
expect(timestamps).to.have.length(6);
|
||||
expect(await timestamps[0].getVisibleText()).to.be('2024-06-10T16:30:00.000Z');
|
||||
expect(await timestamps[5].getVisibleText()).to.be('2024-06-10T14:00:00.000Z');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('data view mode', () => {
|
||||
describe('cell renderers', () => {
|
||||
it('should render custom @timestamp', async () => {
|
||||
await PageObjects.common.navigateToApp('discover');
|
||||
await dataViews.switchTo('my-example-*');
|
||||
await PageObjects.discover.waitUntilSearchingHasFinished();
|
||||
const timestamps = await testSubjects.findAll('exampleRootProfileTimestamp');
|
||||
expect(timestamps).to.have.length(6);
|
||||
expect(await timestamps[0].getVisibleText()).to.be('2024-06-10T16:30:00.000Z');
|
||||
expect(await timestamps[5].getVisibleText()).to.be('2024-06-10T14:00:00.000Z');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
26
test/functional/apps/discover/context_awareness/config.ts
Normal file
26
test/functional/apps/discover/context_awareness/config.ts
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* 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 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 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { FtrConfigProviderContext } from '@kbn/test';
|
||||
|
||||
export default async function ({ readConfigFile }: FtrConfigProviderContext) {
|
||||
const functionalConfig = await readConfigFile(require.resolve('../../../config.base.js'));
|
||||
const baseConfig = functionalConfig.getAll();
|
||||
|
||||
return {
|
||||
...baseConfig,
|
||||
testFiles: [require.resolve('.')],
|
||||
kbnTestServer: {
|
||||
...baseConfig.kbnTestServer,
|
||||
serverArgs: [
|
||||
...baseConfig.kbnTestServer.serverArgs,
|
||||
'--discover.experimental.enabledProfiles=["example-root-profile","example-data-source-profile","example-document-profile"]',
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
39
test/functional/apps/discover/context_awareness/index.ts
Normal file
39
test/functional/apps/discover/context_awareness/index.ts
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* 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 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 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
import { FtrProviderContext } from '../ftr_provider_context';
|
||||
|
||||
export default function ({ getService, getPageObjects, loadTestFile }: FtrProviderContext) {
|
||||
const esArchiver = getService('esArchiver');
|
||||
const kibanaServer = getService('kibanaServer');
|
||||
const PageObjects = getPageObjects(['timePicker']);
|
||||
const from = '2024-06-10T14:00:00.000Z';
|
||||
const to = '2024-06-10T16:30:00.000Z';
|
||||
|
||||
describe('discover/context_awareness', () => {
|
||||
before(async () => {
|
||||
await esArchiver.load('test/functional/fixtures/es_archiver/discover/context_awareness');
|
||||
await kibanaServer.importExport.load(
|
||||
'test/functional/fixtures/kbn_archiver/discover/context_awareness'
|
||||
);
|
||||
await kibanaServer.uiSettings.update({
|
||||
'timepicker:timeDefaults': `{ "from": "${from}", "to": "${to}"}`,
|
||||
});
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await esArchiver.unload('test/functional/fixtures/es_archiver/discover/context_awareness');
|
||||
await kibanaServer.importExport.unload(
|
||||
'test/functional/fixtures/kbn_archiver/discover/context_awareness'
|
||||
);
|
||||
await PageObjects.timePicker.resetDefaultAbsoluteRangeViaUiSettings();
|
||||
});
|
||||
|
||||
loadTestFile(require.resolve('./_root_profile'));
|
||||
loadTestFile(require.resolve('./_data_source_profile'));
|
||||
});
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,76 @@
|
|||
{
|
||||
"type": "index",
|
||||
"value": {
|
||||
"aliases": {
|
||||
},
|
||||
"index": "my-example-logs",
|
||||
"mappings": {
|
||||
"properties": {
|
||||
"@timestamp": {
|
||||
"type": "date"
|
||||
},
|
||||
"data_stream": {
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "constant_keyword",
|
||||
"value": "logs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"log": {
|
||||
"properties": {
|
||||
"level": {
|
||||
"type": "keyword"
|
||||
}
|
||||
}
|
||||
},
|
||||
"message": {
|
||||
"type": "match_only_text"
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"index": {
|
||||
"number_of_replicas": "1",
|
||||
"number_of_shards": "1"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
"type": "index",
|
||||
"value": {
|
||||
"aliases": {
|
||||
},
|
||||
"index": "my-example-metrics",
|
||||
"mappings": {
|
||||
"properties": {
|
||||
"@timestamp": {
|
||||
"type": "date"
|
||||
},
|
||||
"data_stream": {
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "constant_keyword",
|
||||
"value": "metrics"
|
||||
}
|
||||
}
|
||||
},
|
||||
"event": {
|
||||
"properties": {
|
||||
"duration": {
|
||||
"type": "long"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"index": {
|
||||
"number_of_replicas": "1",
|
||||
"number_of_shards": "1"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
{
|
||||
"attributes": {
|
||||
"allowHidden": false,
|
||||
"fieldAttrs": "{}",
|
||||
"fieldFormatMap": "{}",
|
||||
"fields": "[]",
|
||||
"name": "my-example-*",
|
||||
"runtimeFieldMap": "{}",
|
||||
"sourceFilters": "[]",
|
||||
"timeFieldName": "@timestamp",
|
||||
"title": "my-example-*"
|
||||
},
|
||||
"coreMigrationVersion": "8.8.0",
|
||||
"created_at": "2024-06-12T22:23:09.061Z",
|
||||
"created_by": "u_mGBROF_q5bmFCATbLXAcCwKa0k8JvONAwSruelyKA5E_0",
|
||||
"id": "47fbfd7b-a51d-442b-86ff-b1529cf5b935",
|
||||
"managed": false,
|
||||
"references": [],
|
||||
"type": "index-pattern",
|
||||
"typeMigrationVersion": "8.0.0",
|
||||
"updated_at": "2024-06-12T22:23:09.061Z",
|
||||
"updated_by": "u_mGBROF_q5bmFCATbLXAcCwKa0k8JvONAwSruelyKA5E_0",
|
||||
"version": "WzgsMV0="
|
||||
}
|
||||
|
||||
{
|
||||
"attributes": {
|
||||
"allowHidden": false,
|
||||
"fieldAttrs": "{}",
|
||||
"fieldFormatMap": "{}",
|
||||
"fields": "[]",
|
||||
"name": "my-example-logs",
|
||||
"runtimeFieldMap": "{}",
|
||||
"sourceFilters": "[]",
|
||||
"timeFieldName": "@timestamp",
|
||||
"title": "my-example-logs"
|
||||
},
|
||||
"coreMigrationVersion": "8.8.0",
|
||||
"created_at": "2024-06-12T22:23:21.331Z",
|
||||
"created_by": "u_mGBROF_q5bmFCATbLXAcCwKa0k8JvONAwSruelyKA5E_0",
|
||||
"id": "795df528-add1-491a-8e25-72a862c4bf8c",
|
||||
"managed": false,
|
||||
"references": [],
|
||||
"type": "index-pattern",
|
||||
"typeMigrationVersion": "8.0.0",
|
||||
"updated_at": "2024-06-12T22:23:21.331Z",
|
||||
"updated_by": "u_mGBROF_q5bmFCATbLXAcCwKa0k8JvONAwSruelyKA5E_0",
|
||||
"version": "WzEwLDFd"
|
||||
}
|
|
@ -126,6 +126,7 @@ export default function ({ getService }: PluginFunctionalProviderContext) {
|
|||
'data_views.scriptedFieldsEnabled (any)', // It's a boolean (any because schema.conditional)
|
||||
'data_visualizer.resultLinks.fileBeat.enabled (boolean)',
|
||||
'dev_tools.deeplinks.navLinkStatus (string)',
|
||||
'discover.experimental.enabledProfiles (array)',
|
||||
'enterpriseSearch.canDeployEntSearch (boolean)',
|
||||
'enterpriseSearch.host (string)',
|
||||
'enterpriseSearch.ui.enabled (boolean)',
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* 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 kbnRison from '@kbn/rison';
|
||||
import expect from '@kbn/expect';
|
||||
import type { FtrProviderContext } from '../../../../ftr_provider_context';
|
||||
|
||||
export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
||||
const PageObjects = getPageObjects(['common', 'timePicker', 'discover', 'unifiedFieldList']);
|
||||
const testSubjects = getService('testSubjects');
|
||||
const dataViews = getService('dataViews');
|
||||
|
||||
describe('data source profile', () => {
|
||||
describe('ES|QL mode', () => {
|
||||
describe('cell renderers', () => {
|
||||
it('should not render custom @timestamp or log.level', async () => {
|
||||
const state = kbnRison.encode({
|
||||
dataSource: { type: 'esql' },
|
||||
query: { esql: 'from my-example-* | sort @timestamp desc' },
|
||||
});
|
||||
await PageObjects.common.navigateToApp('discover', {
|
||||
hash: `/?_a=${state}`,
|
||||
});
|
||||
await PageObjects.discover.waitUntilSearchingHasFinished();
|
||||
await PageObjects.unifiedFieldList.clickFieldListItemAdd('@timestamp');
|
||||
await PageObjects.unifiedFieldList.clickFieldListItemAdd('log.level');
|
||||
const timestamps = await testSubjects.findAll('exampleRootProfileTimestamp', 2500);
|
||||
expect(timestamps).to.have.length(0);
|
||||
const logLevels = await testSubjects.findAll('exampleDataSourceProfileLogLevel', 2500);
|
||||
expect(logLevels).to.have.length(0);
|
||||
});
|
||||
|
||||
it('should not render custom @timestamp but should render custom log.level', async () => {
|
||||
const state = kbnRison.encode({
|
||||
dataSource: { type: 'esql' },
|
||||
query: { esql: 'from my-example-logs | sort @timestamp desc' },
|
||||
});
|
||||
await PageObjects.common.navigateToApp('discover', {
|
||||
hash: `/?_a=${state}`,
|
||||
});
|
||||
await PageObjects.discover.waitUntilSearchingHasFinished();
|
||||
await PageObjects.unifiedFieldList.clickFieldListItemAdd('@timestamp');
|
||||
await PageObjects.unifiedFieldList.clickFieldListItemAdd('log.level');
|
||||
const timestamps = await testSubjects.findAll('exampleRootProfileTimestamp', 2500);
|
||||
expect(timestamps).to.have.length(0);
|
||||
const logLevels = await testSubjects.findAll('exampleDataSourceProfileLogLevel');
|
||||
expect(logLevels).to.have.length(3);
|
||||
expect(await logLevels[0].getVisibleText()).to.be('Debug');
|
||||
expect(await logLevels[2].getVisibleText()).to.be('Info');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('data view mode', () => {
|
||||
describe('cell renderers', () => {
|
||||
it('should not render custom @timestamp or log.level', async () => {
|
||||
await PageObjects.common.navigateToApp('discover');
|
||||
await dataViews.switchTo('my-example-*');
|
||||
await PageObjects.discover.waitUntilSearchingHasFinished();
|
||||
await PageObjects.unifiedFieldList.clickFieldListItemAdd('@timestamp');
|
||||
await PageObjects.unifiedFieldList.clickFieldListItemAdd('log.level');
|
||||
const timestamps = await testSubjects.findAll('exampleRootProfileTimestamp', 2500);
|
||||
expect(timestamps).to.have.length(0);
|
||||
const logLevels = await testSubjects.findAll('exampleDataSourceProfileLogLevel', 2500);
|
||||
expect(logLevels).to.have.length(0);
|
||||
});
|
||||
|
||||
it('should not render custom @timestamp but should render custom log.level', async () => {
|
||||
await PageObjects.common.navigateToApp('discover');
|
||||
await dataViews.switchTo('my-example-logs');
|
||||
await PageObjects.discover.waitUntilSearchingHasFinished();
|
||||
await PageObjects.unifiedFieldList.clickFieldListItemAdd('@timestamp');
|
||||
await PageObjects.unifiedFieldList.clickFieldListItemAdd('log.level');
|
||||
const timestamps = await testSubjects.findAll('exampleRootProfileTimestamp', 2500);
|
||||
expect(timestamps).to.have.length(0);
|
||||
const logLevels = await testSubjects.findAll('exampleDataSourceProfileLogLevel');
|
||||
expect(logLevels).to.have.length(3);
|
||||
expect(await logLevels[0].getVisibleText()).to.be('Debug');
|
||||
expect(await logLevels[2].getVisibleText()).to.be('Info');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* 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 kbnRison from '@kbn/rison';
|
||||
import expect from '@kbn/expect';
|
||||
import type { FtrProviderContext } from '../../../../ftr_provider_context';
|
||||
|
||||
export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
||||
const PageObjects = getPageObjects(['common', 'timePicker', 'discover']);
|
||||
const testSubjects = getService('testSubjects');
|
||||
const dataViews = getService('dataViews');
|
||||
|
||||
describe('root profile', () => {
|
||||
describe('ES|QL mode', () => {
|
||||
describe('cell renderers', () => {
|
||||
it('should not render custom @timestamp', async () => {
|
||||
const state = kbnRison.encode({
|
||||
dataSource: { type: 'esql' },
|
||||
query: { esql: 'from my-example-* | sort @timestamp desc' },
|
||||
});
|
||||
await PageObjects.common.navigateToApp('discover', {
|
||||
hash: `/?_a=${state}`,
|
||||
});
|
||||
await PageObjects.discover.waitUntilSearchingHasFinished();
|
||||
const timestamps = await testSubjects.findAll('exampleRootProfileTimestamp', 2500);
|
||||
expect(timestamps).to.have.length(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('data view mode', () => {
|
||||
describe('cell renderers', () => {
|
||||
it('should not render custom @timestamp', async () => {
|
||||
await PageObjects.common.navigateToApp('discover');
|
||||
await dataViews.switchTo('my-example-*');
|
||||
await PageObjects.discover.waitUntilSearchingHasFinished();
|
||||
const timestamps = await testSubjects.findAll('exampleRootProfileTimestamp', 2500);
|
||||
expect(timestamps).to.have.length(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* 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 type { FtrProviderContext } from '../../../../ftr_provider_context';
|
||||
|
||||
export default function ({ getService, getPageObjects, loadTestFile }: FtrProviderContext) {
|
||||
const esArchiver = getService('esArchiver');
|
||||
const kibanaServer = getService('kibanaServer');
|
||||
const PageObjects = getPageObjects(['timePicker', 'svlCommonPage']);
|
||||
const from = '2024-06-10T14:00:00.000Z';
|
||||
const to = '2024-06-10T16:30:00.000Z';
|
||||
|
||||
describe('discover/context_awareness', () => {
|
||||
before(async () => {
|
||||
await esArchiver.load('test/functional/fixtures/es_archiver/discover/context_awareness');
|
||||
await kibanaServer.importExport.load(
|
||||
'test/functional/fixtures/kbn_archiver/discover/context_awareness'
|
||||
);
|
||||
await kibanaServer.uiSettings.update({
|
||||
'timepicker:timeDefaults': `{ "from": "${from}", "to": "${to}"}`,
|
||||
});
|
||||
await PageObjects.svlCommonPage.login();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await esArchiver.unload('test/functional/fixtures/es_archiver/discover/context_awareness');
|
||||
await kibanaServer.importExport.unload(
|
||||
'test/functional/fixtures/kbn_archiver/discover/context_awareness'
|
||||
);
|
||||
await PageObjects.timePicker.resetDefaultAbsoluteRangeViaUiSettings();
|
||||
});
|
||||
|
||||
loadTestFile(require.resolve('./_root_profile'));
|
||||
loadTestFile(require.resolve('./_data_source_profile'));
|
||||
});
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* 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 { createTestConfig } from '../../config.base';
|
||||
|
||||
export default createTestConfig({
|
||||
serverlessProject: 'oblt',
|
||||
testFiles: [require.resolve('../common/discover/context_awareness')],
|
||||
junit: {
|
||||
reportName: 'Serverless Observability Discover Context Awareness Functional Tests',
|
||||
},
|
||||
kbnServerArgs: [
|
||||
'--discover.experimental.enabledProfiles=["example-root-profile","example-data-source-profile","example-document-profile"]',
|
||||
],
|
||||
// include settings from project controller
|
||||
// https://github.com/elastic/project-controller/blob/main/internal/project/observability/config/elasticsearch.yml
|
||||
esServerArgs: ['xpack.ml.dfa.enabled=false'],
|
||||
});
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* 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 { createTestConfig } from '../../config.base';
|
||||
|
||||
export default createTestConfig({
|
||||
serverlessProject: 'es',
|
||||
testFiles: [require.resolve('../common/discover/context_awareness')],
|
||||
junit: {
|
||||
reportName: 'Serverless Search Discover Context Awareness Functional Tests',
|
||||
},
|
||||
kbnServerArgs: [
|
||||
'--discover.experimental.enabledProfiles=["example-root-profile","example-data-source-profile","example-document-profile"]',
|
||||
],
|
||||
// include settings from project controller
|
||||
// https://github.com/elastic/project-controller/blob/main/internal/project/observability/config/elasticsearch.yml
|
||||
esServerArgs: ['xpack.ml.dfa.enabled=false'],
|
||||
});
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* 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 { createTestConfig } from '../../config.base';
|
||||
|
||||
export default createTestConfig({
|
||||
serverlessProject: 'security',
|
||||
testFiles: [require.resolve('../common/discover/context_awareness')],
|
||||
junit: {
|
||||
reportName: 'Serverless Security Discover Context Awareness Functional Tests',
|
||||
},
|
||||
kbnServerArgs: [
|
||||
'--discover.experimental.enabledProfiles=["example-root-profile","example-data-source-profile","example-document-profile"]',
|
||||
],
|
||||
// include settings from project controller
|
||||
// https://github.com/elastic/project-controller/blob/main/internal/project/observability/config/elasticsearch.yml
|
||||
esServerArgs: ['xpack.ml.dfa.enabled=false'],
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue