@@ -195,15 +241,19 @@ export function DiscoverHistogram({
xAxisFormatter.convert(value)}
+ gridLine={gridLineStyle}
+ style={verticalAxisStyle}
/>
diff --git a/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts b/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts
index 007d3a99cb1dd8..d8d0215fd751f2 100644
--- a/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts
+++ b/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts
@@ -64,6 +64,10 @@ export const stackManagementSchema: MakeSchemaFrom = {
type: 'text',
_meta: { description: 'Non-default value of setting.' },
},
+ 'visualization:useLegacyTimeAxis': {
+ type: 'boolean',
+ _meta: { description: 'Non-default value of setting.' },
+ },
'visualization:regionmap:showWarnings': {
type: 'boolean',
_meta: { description: 'Non-default value of setting.' },
@@ -436,10 +440,6 @@ export const stackManagementSchema: MakeSchemaFrom = {
type: 'boolean',
_meta: { description: 'Non-default value of setting.' },
},
- 'labs:canvas:byValueEmbeddable': {
- type: 'boolean',
- _meta: { description: 'Non-default value of setting.' },
- },
'labs:canvas:useDataService': {
type: 'boolean',
_meta: { description: 'Non-default value of setting.' },
diff --git a/src/plugins/kibana_usage_collection/server/collectors/management/types.ts b/src/plugins/kibana_usage_collection/server/collectors/management/types.ts
index d35a05fe04780b..9dcd2038edb9d7 100644
--- a/src/plugins/kibana_usage_collection/server/collectors/management/types.ts
+++ b/src/plugins/kibana_usage_collection/server/collectors/management/types.ts
@@ -40,6 +40,7 @@ export interface UsageStats {
'visualize:enableLabs': boolean;
'visualization:heatmap:maxBuckets': number;
'visualization:colorMapping': string;
+ 'visualization:useLegacyTimeAxis': boolean;
'visualization:regionmap:showWarnings': boolean;
'visualization:tileMap:maxPrecision': number;
'csv:separator': string;
@@ -120,7 +121,6 @@ export interface UsageStats {
'banners:textColor': string;
'banners:backgroundColor': string;
'labs:canvas:enable_ui': boolean;
- 'labs:canvas:byValueEmbeddable': boolean;
'labs:canvas:useDataService': boolean;
'labs:presentation:timeToPresent': boolean;
'labs:dashboard:enable_ui': boolean;
diff --git a/src/plugins/presentation_util/common/labs.ts b/src/plugins/presentation_util/common/labs.ts
index 8eefbd6981280c..cb976e73b5edfe 100644
--- a/src/plugins/presentation_util/common/labs.ts
+++ b/src/plugins/presentation_util/common/labs.ts
@@ -11,9 +11,7 @@ import { i18n } from '@kbn/i18n';
export const LABS_PROJECT_PREFIX = 'labs:';
export const DEFER_BELOW_FOLD = `${LABS_PROJECT_PREFIX}dashboard:deferBelowFold` as const;
export const DASHBOARD_CONTROLS = `${LABS_PROJECT_PREFIX}dashboard:dashboardControls` as const;
-export const BY_VALUE_EMBEDDABLE = `${LABS_PROJECT_PREFIX}canvas:byValueEmbeddable` as const;
-
-export const projectIDs = [DEFER_BELOW_FOLD, DASHBOARD_CONTROLS, BY_VALUE_EMBEDDABLE] as const;
+export const projectIDs = [DEFER_BELOW_FOLD, DASHBOARD_CONTROLS] as const;
export const environmentNames = ['kibana', 'browser', 'session'] as const;
export const solutionNames = ['canvas', 'dashboard', 'presentation'] as const;
@@ -50,19 +48,6 @@ export const projects: { [ID in ProjectID]: ProjectConfig & { id: ID } } = {
}),
solutions: ['dashboard'],
},
- [BY_VALUE_EMBEDDABLE]: {
- id: BY_VALUE_EMBEDDABLE,
- isActive: true,
- isDisplayed: true,
- environments: ['kibana', 'browser', 'session'],
- name: i18n.translate('presentationUtil.labs.enableByValueEmbeddableName', {
- defaultMessage: 'By-Value Embeddables',
- }),
- description: i18n.translate('presentationUtil.labs.enableByValueEmbeddableDescription', {
- defaultMessage: 'Enables support for by-value embeddables in Canvas',
- }),
- solutions: ['canvas'],
- },
};
export type ProjectID = typeof projectIDs[number];
diff --git a/src/plugins/presentation_util/public/components/solution_toolbar/items/quick_group.scss b/src/plugins/presentation_util/public/components/solution_toolbar/items/quick_group.scss
index c70e317546d403..535570a51d777c 100644
--- a/src/plugins/presentation_util/public/components/solution_toolbar/items/quick_group.scss
+++ b/src/plugins/presentation_util/public/components/solution_toolbar/items/quick_group.scss
@@ -1,31 +1,11 @@
.quickButtonGroup {
- .euiButtonGroup__buttons {
- border-radius: $euiBorderRadius;
-
- .quickButtonGroup__button {
- background-color: $euiColorEmptyShade;
- @include kbnThemeStyle('v8') {
- // sass-lint:disable-block no-important
- border-width: $euiBorderWidthThin !important;
- border-style: solid !important;
- border-color: $euiBorderColor !important;
- }
- }
-
- .quickButtonGroup__button:first-of-type {
- @include kbnThemeStyle('v8') {
- // sass-lint:disable-block no-important
- border-top-left-radius: $euiBorderRadius !important;
- border-bottom-left-radius: $euiBorderRadius !important;
- }
- }
-
- .quickButtonGroup__button:last-of-type {
- @include kbnThemeStyle('v8') {
- // sass-lint:disable-block no-important
- border-top-right-radius: $euiBorderRadius !important;
- border-bottom-right-radius: $euiBorderRadius !important;
- }
+ .quickButtonGroup__button {
+ background-color: $euiColorEmptyShade;
+ @include kbnThemeStyle('v8') {
+ // sass-lint:disable-block no-important
+ border-width: $euiBorderWidthThin !important;
+ border-style: solid !important;
+ border-color: $euiBorderColor !important;
}
}
}
diff --git a/src/plugins/telemetry/schema/oss_plugins.json b/src/plugins/telemetry/schema/oss_plugins.json
index 138ce3f097ce96..251fed955788eb 100644
--- a/src/plugins/telemetry/schema/oss_plugins.json
+++ b/src/plugins/telemetry/schema/oss_plugins.json
@@ -7110,6 +7110,12 @@
"description": "Non-default value of setting."
}
},
+ "visualization:useLegacyTimeAxis": {
+ "type": "boolean",
+ "_meta": {
+ "description": "Non-default value of setting."
+ }
+ },
"visualization:regionmap:showWarnings": {
"type": "boolean",
"_meta": {
@@ -7671,12 +7677,6 @@
"description": "Non-default value of setting."
}
},
- "labs:canvas:byValueEmbeddable": {
- "type": "boolean",
- "_meta": {
- "description": "Non-default value of setting."
- }
- },
"labs:canvas:useDataService": {
"type": "boolean",
"_meta": {
diff --git a/src/plugins/vis_types/timeseries/public/application/components/vis_types/timeseries/vis.js b/src/plugins/vis_types/timeseries/public/application/components/vis_types/timeseries/vis.js
index b4fe39c522de76..b177ef632e2107 100644
--- a/src/plugins/vis_types/timeseries/public/application/components/vis_types/timeseries/vis.js
+++ b/src/plugins/vis_types/timeseries/public/application/components/vis_types/timeseries/vis.js
@@ -19,6 +19,7 @@ import { createFieldFormatter } from '../../lib/create_field_formatter';
import { checkIfSeriesHaveSameFormatters } from '../../lib/check_if_series_have_same_formatters';
import { TimeSeries } from '../../../visualizations/views/timeseries';
import { MarkdownSimple } from '../../../../../../../../plugins/kibana_react/public';
+import { LEGACY_TIME_AXIS } from '../../../../../../../../plugins/charts/common';
import { replaceVars } from '../../lib/replace_vars';
import { getInterval } from '../../lib/get_interval';
import { createIntervalBasedFormatter } from '../../lib/create_interval_based_formatter';
@@ -272,6 +273,7 @@ class TimeseriesVisualization extends Component {
syncColors={syncColors}
palettesService={palettesService}
interval={interval}
+ useLegacyTimeAxis={getConfig(LEGACY_TIME_AXIS, false)}
isLastBucketDropped={Boolean(
model.drop_last_bucket ||
model.series.some((series) => series.series_drop_last_bucket)
diff --git a/src/plugins/vis_types/timeseries/public/application/visualizations/views/timeseries/index.js b/src/plugins/vis_types/timeseries/public/application/visualizations/views/timeseries/index.js
index 2158283bb80d57..5e98b74c0caa5b 100644
--- a/src/plugins/vis_types/timeseries/public/application/visualizations/views/timeseries/index.js
+++ b/src/plugins/vis_types/timeseries/public/application/visualizations/views/timeseries/index.js
@@ -72,6 +72,7 @@ export const TimeSeries = ({
palettesService,
interval,
isLastBucketDropped,
+ useLegacyTimeAxis,
}) => {
// If the color isn't configured by the user, use the color mapping service
// to assign a color from the Kibana palette. Colors will be shared across the
@@ -138,6 +139,51 @@ export const TimeSeries = ({
},
[palettesService, series, syncColors]
);
+
+ const darkMode = uiSettings.get('theme:darkMode');
+ const gridLineStyle = !useLegacyTimeAxis
+ ? {
+ visible: showGrid,
+ strokeWidth: 0.1,
+ stroke: darkMode ? 'white' : 'black',
+ }
+ : {
+ ...GRID_LINE_CONFIG,
+ visible: showGrid,
+ };
+ const xAxisStyle = !useLegacyTimeAxis
+ ? {
+ tickLabel: {
+ visible: true,
+ fontSize: 11,
+ padding: 0,
+ alignment: {
+ vertical: Position.Bottom,
+ horizontal: Position.Left,
+ },
+ offset: {
+ x: 1.5,
+ y: 0,
+ },
+ },
+ axisLine: {
+ stroke: darkMode ? 'lightgray' : 'darkgray',
+ strokeWidth: 1,
+ },
+ tickLine: {
+ size: 12,
+ strokeWidth: 0.15,
+ stroke: darkMode ? 'white' : 'black',
+ padding: -10,
+ visible: true,
+ },
+ axisTitle: {
+ visible: true,
+ padding: 0,
+ },
+ }
+ : {};
+
return (
);
@@ -357,4 +402,5 @@ TimeSeries.propTypes = {
annotations: PropTypes.array,
interval: PropTypes.number,
isLastBucketDropped: PropTypes.bool,
+ useLegacyTimeAxis: PropTypes.bool,
};
diff --git a/src/plugins/vis_types/xy/public/components/xy_axis.tsx b/src/plugins/vis_types/xy/public/components/xy_axis.tsx
index 30e1dbbff673ee..b224639bdbff3a 100644
--- a/src/plugins/vis_types/xy/public/components/xy_axis.tsx
+++ b/src/plugins/vis_types/xy/public/components/xy_axis.tsx
@@ -25,6 +25,7 @@ export const XYAxis: FC = ({
domain,
style,
integersOnly,
+ timeAxisLayerCount,
}) => (
= ({
labelFormat={ticks?.labelFormatter}
showOverlappingLabels={ticks?.showOverlappingLabels}
showDuplicatedTicks={ticks?.showDuplicates}
+ timeAxisLayerCount={timeAxisLayerCount}
/>
);
diff --git a/src/plugins/vis_types/xy/public/config/get_axis.ts b/src/plugins/vis_types/xy/public/config/get_axis.ts
index 0d6c67d064cf82..796636ef2cb61f 100644
--- a/src/plugins/vis_types/xy/public/config/get_axis.ts
+++ b/src/plugins/vis_types/xy/public/config/get_axis.ts
@@ -8,7 +8,13 @@
import { identity } from 'lodash';
-import { AxisSpec, TickFormatter, YDomainRange, ScaleType as ECScaleType } from '@elastic/charts';
+import {
+ AxisSpec,
+ TickFormatter,
+ YDomainRange,
+ ScaleType as ECScaleType,
+ Position,
+} from '@elastic/charts';
import { LabelRotation } from '../../../../charts/public';
import { BUCKET_TYPES } from '../../../../data/public';
@@ -33,7 +39,9 @@ export function getAxis(
{ categoryLines, valueAxis }: Grid,
{ params, format, formatter, title: fallbackTitle = '', aggType }: Aspect,
seriesParams: SeriesParam[],
- isDateHistogram = false
+ isDateHistogram = false,
+ useMultiLayerTimeAxis = false,
+ darkMode = false
): AxisConfig {
const isCategoryAxis = type === AxisType.Category;
// Hide unassigned axis, not supported in elastic charts
@@ -74,9 +82,10 @@ export function getAxis(
ticks,
grid,
scale,
- style: getAxisStyle(ticks, title, fallbackRotation),
+ style: getAxisStyle(useMultiLayerTimeAxis, darkMode, ticks, title, fallbackRotation),
domain: getAxisDomain(scale, isCategoryAxis),
integersOnly: aggType === 'count',
+ timeAxisLayerCount: useMultiLayerTimeAxis ? 3 : 0,
};
}
@@ -147,19 +156,52 @@ export function getScale(
}
function getAxisStyle(
+ isMultiLayerTimeAxis: boolean,
+ darkMode: boolean,
ticks?: TickOptions,
title?: string,
rotationFallback: LabelRotation = LabelRotation.Vertical
): AxisSpec['style'] {
- return {
- axisTitle: {
- visible: (title ?? '').trim().length > 0,
- },
- tickLabel: {
- visible: ticks?.show,
- rotation: -(ticks?.rotation ?? rotationFallback),
- },
- };
+ return isMultiLayerTimeAxis
+ ? {
+ tickLabel: {
+ visible: Boolean(ticks?.show),
+ rotation: 0, // rotation is disabled on new time axis
+ fontSize: 11,
+ padding: 0,
+ alignment: {
+ vertical: Position.Bottom,
+ horizontal: Position.Left,
+ },
+ offset: {
+ x: 1.5,
+ y: 0,
+ },
+ },
+ axisLine: {
+ stroke: darkMode ? 'lightgray' : 'darkgray',
+ strokeWidth: 1,
+ },
+ tickLine: {
+ size: 12,
+ strokeWidth: 0.15,
+ stroke: darkMode ? 'white' : 'black',
+ padding: -10,
+ visible: Boolean(ticks?.show),
+ },
+ axisTitle: {
+ visible: (title ?? '').trim().length > 0,
+ },
+ }
+ : {
+ axisTitle: {
+ visible: (title ?? '').trim().length > 0,
+ },
+ tickLabel: {
+ visible: ticks?.show,
+ rotation: -(ticks?.rotation ?? rotationFallback),
+ },
+ };
}
function getAxisDomain(
diff --git a/src/plugins/vis_types/xy/public/config/get_config.ts b/src/plugins/vis_types/xy/public/config/get_config.ts
index d2a3b9ad2a1037..bd79b915be9172 100644
--- a/src/plugins/vis_types/xy/public/config/get_config.ts
+++ b/src/plugins/vis_types/xy/public/config/get_config.ts
@@ -29,7 +29,12 @@ import { getAxis } from './get_axis';
import { getAspects } from './get_aspects';
import { ChartType } from '../index';
-export function getConfig(table: Datatable, params: VisParams): VisConfig {
+export function getConfig(
+ table: Datatable,
+ params: VisParams,
+ useLegacyTimeAxis = false,
+ darkMode = false
+): VisConfig {
const {
thresholdLine,
orderBucketsBySum,
@@ -42,13 +47,6 @@ export function getConfig(table: Datatable, params: VisParams): VisConfig {
fillOpacity,
} = params;
const aspects = getAspects(table.columns, params.dimensions);
- const xAxis = getAxis(
- params.categoryAxes[0],
- params.grid,
- aspects.x,
- params.seriesParams,
- params.dimensions.x?.aggType === BUCKET_TYPES.DATE_HISTOGRAM
- );
const tooltip = getTooltip(aspects, params);
const yAxes = params.valueAxes.map((a) => {
// find the correct aspect for each value axis
@@ -60,10 +58,28 @@ export function getConfig(table: Datatable, params: VisParams): VisConfig {
params.seriesParams
);
});
+
+ const rotation = getRotation(params.categoryAxes[0]);
+
+ const isDateHistogram = params.dimensions.x?.aggType === BUCKET_TYPES.DATE_HISTOGRAM;
+ const isHistogram = params.dimensions.x?.aggType === BUCKET_TYPES.HISTOGRAM;
const enableHistogramMode =
- (params.dimensions.x?.aggType === BUCKET_TYPES.DATE_HISTOGRAM ||
- params.dimensions.x?.aggType === BUCKET_TYPES.HISTOGRAM) &&
+ (isDateHistogram || isHistogram) &&
shouldEnableHistogramMode(params.seriesParams, aspects.y, yAxes);
+
+ const useMultiLayerTimeAxis =
+ enableHistogramMode && isDateHistogram && !useLegacyTimeAxis && rotation === 0;
+
+ const xAxis = getAxis(
+ params.categoryAxes[0],
+ params.grid,
+ aspects.x,
+ params.seriesParams,
+ isDateHistogram,
+ useMultiLayerTimeAxis,
+ darkMode
+ );
+
const isTimeChart = (aspects.x.params as DateHistogramParams).date ?? false;
return {
@@ -83,7 +99,7 @@ export function getConfig(table: Datatable, params: VisParams): VisConfig {
xAxis,
yAxes,
legend: getLegend(params),
- rotation: getRotation(params.categoryAxes[0]),
+ rotation,
thresholdLine: getThresholdLine(thresholdLine, yAxes, params.seriesParams),
};
}
diff --git a/src/plugins/vis_types/xy/public/plugin.ts b/src/plugins/vis_types/xy/public/plugin.ts
index c79ead242e35b0..0f1de387161e30 100644
--- a/src/plugins/vis_types/xy/public/plugin.ts
+++ b/src/plugins/vis_types/xy/public/plugin.ts
@@ -24,7 +24,7 @@ import {
} from './services';
import { visTypesDefinitions } from './vis_types';
-import { xyVisRenderer } from './vis_renderer';
+import { getXYVisRenderer } from './vis_renderer';
import * as expressionFunctions from './expression_functions';
@@ -69,7 +69,11 @@ export class VisTypeXyPlugin
setThemeService(charts.theme);
setPalettesService(charts.palettes);
- expressions.registerRenderer(xyVisRenderer);
+ expressions.registerRenderer(
+ getXYVisRenderer({
+ uiSettings: core.uiSettings,
+ })
+ );
expressions.registerFunction(expressionFunctions.visTypeXyVisFn);
expressions.registerFunction(expressionFunctions.categoryAxis);
expressions.registerFunction(expressionFunctions.timeMarker);
diff --git a/src/plugins/vis_types/xy/public/types/config.ts b/src/plugins/vis_types/xy/public/types/config.ts
index e52b47366bc857..287787193bd202 100644
--- a/src/plugins/vis_types/xy/public/types/config.ts
+++ b/src/plugins/vis_types/xy/public/types/config.ts
@@ -85,6 +85,7 @@ export interface AxisConfig {
title?: string;
grid?: AxisGrid;
integersOnly: boolean;
+ timeAxisLayerCount?: number;
}
export interface LegendOptions {
diff --git a/src/plugins/vis_types/xy/public/vis_component.tsx b/src/plugins/vis_types/xy/public/vis_component.tsx
index 515ad3e7eaf6fa..8574e86a230962 100644
--- a/src/plugins/vis_types/xy/public/vis_component.tsx
+++ b/src/plugins/vis_types/xy/public/vis_component.tsx
@@ -66,6 +66,7 @@ export interface VisComponentProps {
fireEvent: IInterpreterRenderHandlers['event'];
renderComplete: IInterpreterRenderHandlers['done'];
syncColors: boolean;
+ useLegacyTimeAxis: boolean;
}
export type VisComponentType = typeof VisComponent;
@@ -211,8 +212,9 @@ const VisComponent = (props: VisComponentProps) => {
);
const { visData, visParams, syncColors } = props;
+ const isDarkMode = getThemeService().useDarkMode();
- const config = getConfig(visData, visParams);
+ const config = getConfig(visData, visParams, props.useLegacyTimeAxis, isDarkMode);
const timeZone = getTimeZone();
const xDomain =
config.xAxis.scale.type === ScaleType.Ordinal ? undefined : getXDomain(config.aspects.x.params);
@@ -229,7 +231,7 @@ const VisComponent = (props: VisComponentProps) => {
() => config.legend.position ?? Position.Right,
[config.legend.position]
);
- const isDarkMode = getThemeService().useDarkMode();
+
const getSeriesName = getSeriesNameFn(config.aspects, config.aspects.y.length > 1);
const splitAccessors = config.aspects.series?.map(({ accessor, formatter }) => {
diff --git a/src/plugins/vis_types/xy/public/vis_renderer.tsx b/src/plugins/vis_types/xy/public/vis_renderer.tsx
index 093671307d5383..77727761015a74 100644
--- a/src/plugins/vis_types/xy/public/vis_renderer.tsx
+++ b/src/plugins/vis_types/xy/public/vis_renderer.tsx
@@ -9,6 +9,7 @@
import React, { lazy } from 'react';
import { render, unmountComponentAtNode } from 'react-dom';
import { I18nProvider } from '@kbn/i18n/react';
+import { IUiSettingsClient } from 'kibana/public';
import { VisualizationContainer } from '../../../visualizations/public';
import type { PersistedState } from '../../../visualizations/public';
@@ -17,6 +18,7 @@ import type { ExpressionRenderDefinition } from '../../../expressions/public';
import type { XyVisType } from '../common';
import type { VisComponentType } from './vis_component';
import { RenderValue, visName } from './expression_functions/xy_vis_fn';
+import { LEGACY_TIME_AXIS } from '../../../charts/common';
// @ts-ignore
const VisComponent = lazy(() => import('./vis_component'));
@@ -28,7 +30,9 @@ function shouldShowNoResultsMessage(visData: any, visType: XyVisType): boolean {
return Boolean(isZeroHits);
}
-export const xyVisRenderer: ExpressionRenderDefinition = {
+export const getXYVisRenderer: (deps: {
+ uiSettings: IUiSettingsClient;
+}) => ExpressionRenderDefinition = ({ uiSettings }) => ({
name: visName,
displayName: 'XY visualization',
reuseDomNode: true,
@@ -46,10 +50,11 @@ export const xyVisRenderer: ExpressionRenderDefinition = {
fireEvent={handlers.event}
uiState={handlers.uiState as PersistedState}
syncColors={syncColors}
+ useLegacyTimeAxis={uiSettings.get(LEGACY_TIME_AXIS, false)}
/>
,
domNode
);
},
-};
+});
diff --git a/test/common/services/bsearch.ts b/test/common/services/bsearch.ts
new file mode 100644
index 00000000000000..d9fe89d9e4b9c7
--- /dev/null
+++ b/test/common/services/bsearch.ts
@@ -0,0 +1,122 @@
+/*
+ * 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 expect from '@kbn/expect';
+import request from 'superagent';
+import type SuperTest from 'supertest';
+import { IEsSearchResponse } from 'src/plugins/data/common';
+import { FtrProviderContext } from '../ftr_provider_context';
+import { RetryService } from './retry/retry';
+
+/**
+ * Function copied from here:
+ * test/api_integration/apis/search/bsearch.ts without the compress
+ *
+ * Splits the JSON lines from bsearch
+ */
+const parseBfetchResponse = (resp: request.Response): Array> => {
+ return resp.text
+ .trim()
+ .split('\n')
+ .map((item) => JSON.parse(item));
+};
+
+/**
+ * Function copied from here:
+ * x-pack/test/rule_registry/common/lib/authentication/spaces.ts
+ * @param spaceId The space id we want to utilize
+ */
+const getSpaceUrlPrefix = (spaceId?: string): string => {
+ return spaceId && spaceId !== 'default' ? `/s/${spaceId}` : ``;
+};
+
+/**
+ * Options for the send method
+ */
+interface SendOptions {
+ supertest: SuperTest.SuperTest;
+ options: object;
+ strategy: string;
+ space?: string;
+}
+
+/**
+ * Bsearch factory which will return a new bsearch capable service that can reduce flake
+ * on the CI systems when they are under pressure and bsearch returns an async search
+ * response or a sync response.
+ *
+ * @example
+ * const supertest = getService('supertest');
+ * const bsearch = getService('bsearch');
+ * const response = await bsearch.send({
+ * supertest,
+ * options: {
+ * defaultIndex: ['large_volume_dns_data'],
+ * }
+ * strategy: 'securitySolutionSearchStrategy',
+ * });
+ * expect(response).eql({ ... your value ... });
+ */
+export const BSearchFactory = (retry: RetryService) => ({
+ /** Send method to send in your supertest, url, options, and strategy name */
+ send: async ({
+ supertest,
+ options,
+ strategy,
+ space,
+ }: SendOptions): Promise => {
+ const spaceUrl = getSpaceUrlPrefix(space);
+ const { body } = await retry.try(async () => {
+ return supertest
+ .post(`${spaceUrl}/internal/search/${strategy}`)
+ .set('kbn-xsrf', 'true')
+ .send(options)
+ .expect(200);
+ });
+
+ if (body.isRunning) {
+ const result = await retry.try(async () => {
+ const resp = await supertest
+ .post(`${spaceUrl}/internal/bsearch`)
+ .set('kbn-xsrf', 'true')
+ .send({
+ batch: [
+ {
+ request: {
+ id: body.id,
+ ...options,
+ },
+ options: {
+ strategy,
+ },
+ },
+ ],
+ })
+ .expect(200);
+ const [parsedResponse] = parseBfetchResponse(resp);
+ expect(parsedResponse.result.isRunning).equal(false);
+ return parsedResponse.result;
+ });
+ return result;
+ } else {
+ return body;
+ }
+ },
+});
+
+/**
+ * Bsearch provider which will return a new bsearch capable service that can reduce flake
+ * on the CI systems when they are under pressure and bsearch returns an async search response
+ * or a sync response.
+ */
+export function BSearchProvider({
+ getService,
+}: FtrProviderContext): ReturnType {
+ const retry = getService('retry');
+ return BSearchFactory(retry);
+}
diff --git a/test/common/services/index.ts b/test/common/services/index.ts
index c04bd778468a9e..91d17ce1bb3e89 100644
--- a/test/common/services/index.ts
+++ b/test/common/services/index.ts
@@ -16,6 +16,7 @@ import { SecurityServiceProvider } from './security';
import { EsDeleteAllIndicesProvider } from './es_delete_all_indices';
import { SavedObjectInfoService } from './saved_object_info';
import { IndexPatternsService } from './index_patterns';
+import { BSearchProvider } from './bsearch';
export const services = {
deployment: DeploymentService,
@@ -28,4 +29,5 @@ export const services = {
esDeleteAllIndices: EsDeleteAllIndicesProvider,
savedObjectInfo: SavedObjectInfoService,
indexPatterns: IndexPatternsService,
+ bsearch: BSearchProvider,
};
diff --git a/test/examples/embeddables/dashboard.ts b/test/examples/embeddables/dashboard.ts
index b97905ca9ce6a6..5c255b136c666d 100644
--- a/test/examples/embeddables/dashboard.ts
+++ b/test/examples/embeddables/dashboard.ts
@@ -100,7 +100,8 @@ export default function ({ getService, getPageObjects }: PluginFunctionalProvide
const PageObjects = getPageObjects(['common', 'visChart']);
const monacoEditor = getService('monacoEditor');
- describe('dashboard container', () => {
+ // FLAKY: https://github.com/elastic/kibana/issues/116414
+ describe.skip('dashboard container', () => {
before(async () => {
await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/dashboard/current/data');
await esArchiver.loadIfNeeded(
diff --git a/test/examples/index_pattern_field_editor_example/index_pattern_field_editor_example.ts b/test/examples/index_pattern_field_editor_example/index_pattern_field_editor_example.ts
index 5744c8e64f5c11..fa4308ae72883a 100644
--- a/test/examples/index_pattern_field_editor_example/index_pattern_field_editor_example.ts
+++ b/test/examples/index_pattern_field_editor_example/index_pattern_field_editor_example.ts
@@ -12,7 +12,8 @@ import { PluginFunctionalProviderContext } from 'test/plugin_functional/services
export default function ({ getService }: PluginFunctionalProviderContext) {
const testSubjects = getService('testSubjects');
- describe('', () => {
+ // FAILING: https://github.com/elastic/kibana/issues/116463
+ describe.skip('', () => {
it('finds an index pattern', async () => {
await testSubjects.existOrFail('indexPatternTitle');
});
diff --git a/test/functional/apps/dashboard/dashboard_snapshots.ts b/test/functional/apps/dashboard/dashboard_snapshots.ts
index 3aba671c0a4b29..9279bbd5806e7b 100644
--- a/test/functional/apps/dashboard/dashboard_snapshots.ts
+++ b/test/functional/apps/dashboard/dashboard_snapshots.ts
@@ -59,7 +59,7 @@ export default function ({
);
await PageObjects.dashboard.clickExitFullScreenLogoButton();
- expect(percentDifference).to.be.lessThan(0.02);
+ expect(percentDifference).to.be.lessThan(0.022);
});
it('compare area chart snapshot', async () => {
@@ -81,7 +81,7 @@ export default function ({
);
await PageObjects.dashboard.clickExitFullScreenLogoButton();
- expect(percentDifference).to.be.lessThan(0.02);
+ expect(percentDifference).to.be.lessThan(0.022);
});
});
}
diff --git a/test/functional/apps/visualize/_timelion.ts b/test/functional/apps/visualize/_timelion.ts
index c531ada8a25737..631d2148d73c39 100644
--- a/test/functional/apps/visualize/_timelion.ts
+++ b/test/functional/apps/visualize/_timelion.ts
@@ -167,7 +167,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
expect(firstAreaChartData).to.eql(firstAreaExpectedChartData);
expect(secondAreaChartData).to.eql(secondAreaExpectedChartData);
expect(thirdAreaChartData).to.eql(thirdAreaExpectedChartData);
- expect(firstAxesLabels).to.eql(['12.19GB', '12.2GB', '12.21GB']);
+ expect(firstAxesLabels).to.eql(['12.2GB', '12.21GB']);
expect(secondAxesLabels).to.eql(['5.59KB', '5.6KB']);
expect(thirdAxesLabels.toString()).to.be(
'BYTES_5721,BYTES_5722,BYTES_5723,BYTES_5724,BYTES_5725,BYTES_5726,BYTES_5727,BYTES_5728,BYTES_5729,BYTES_5730,BYTES_5731,BYTES_5732,BYTES_5733'
@@ -257,8 +257,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
expect(value).to.eql('.es()');
});
- // FLAKY: https://github.com/elastic/kibana/issues/116033
- describe.skip('dynamic suggestions for argument values', () => {
+ describe('dynamic suggestions for argument values', () => {
describe('.es()', () => {
it('should show index pattern suggestions for index argument', async () => {
await monacoEditor.setCodeEditorValue('');
diff --git a/test/functional/config.js b/test/functional/config.js
index 5b0b79e84e8df3..09eccc863a0e53 100644
--- a/test/functional/config.js
+++ b/test/functional/config.js
@@ -54,6 +54,7 @@ export default async function ({ readConfigFile }) {
'accessibility:disableAnimations': true,
'dateFormat:tz': 'UTC',
'visualization:visualize:legacyPieChartsLibrary': true,
+ 'visualization:useLegacyTimeAxis': true,
},
},
diff --git a/test/functional/page_objects/timelion_page.ts b/test/functional/page_objects/timelion_page.ts
index bdfde3c8145e5e..ba1db60bc6350d 100644
--- a/test/functional/page_objects/timelion_page.ts
+++ b/test/functional/page_objects/timelion_page.ts
@@ -7,13 +7,21 @@
*/
import { FtrService } from '../ftr_provider_context';
+import type { WebElementWrapper } from '../services/lib/web_element_wrapper';
export class TimelionPageObject extends FtrService {
private readonly testSubjects = this.ctx.getService('testSubjects');
+ private readonly retry = this.ctx.getService('retry');
public async getSuggestionItemsText() {
- const timelionCodeEditor = await this.testSubjects.find('timelionCodeEditor');
- const lists = await timelionCodeEditor.findAllByClassName('monaco-list-row');
+ let lists: WebElementWrapper[] = [];
+ await this.retry.try(async () => {
+ const timelionCodeEditor = await this.testSubjects.find('timelionCodeEditor');
+ lists = await timelionCodeEditor.findAllByClassName('monaco-list-row');
+ if (lists.length === 0) {
+ throw new Error('suggestion list not populated');
+ }
+ });
return await Promise.all(lists.map(async (element) => await element.getVisibleText()));
}
diff --git a/test/plugin_functional/test_suites/saved_objects_management/hidden_types.ts b/test/plugin_functional/test_suites/saved_objects_management/hidden_types.ts
index 8e7adb504ebee3..b384c3fbbbb1ec 100644
--- a/test/plugin_functional/test_suites/saved_objects_management/hidden_types.ts
+++ b/test/plugin_functional/test_suites/saved_objects_management/hidden_types.ts
@@ -68,7 +68,8 @@ export default function ({ getService, getPageObjects }: PluginFunctionalProvide
});
});
- describe('Delete modal', () => {
+ // FLAKY: https://github.com/elastic/kibana/issues/116059
+ describe.skip('Delete modal', () => {
it('should display a warning then trying to delete hidden saved objects', async () => {
await PageObjects.savedObjects.clickCheckboxByTitle('A Pie');
await PageObjects.savedObjects.clickCheckboxByTitle('A Dashboard');
diff --git a/vars/tasks.groovy b/vars/tasks.groovy
index 0f509fa8ba1327..050b62646fb3bc 100644
--- a/vars/tasks.groovy
+++ b/vars/tasks.groovy
@@ -137,6 +137,7 @@ def functionalXpack(Map params = [:]) {
'x-pack/plugins/security_solution/',
'x-pack/plugins/cases/',
'x-pack/plugins/timelines/',
+ 'x-pack/plugins/lists/',
'x-pack/test/security_solution_cypress/',
'x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/',
'x-pack/plugins/triggers_actions_ui/public/application/context/actions_connectors_context.tsx',
diff --git a/x-pack/package.json b/x-pack/package.json
index 805d8555bf453f..8fb7a3483e5ef0 100644
--- a/x-pack/package.json
+++ b/x-pack/package.json
@@ -1,6 +1,6 @@
{
"name": "x-pack",
- "version": "8.0.0",
+ "version": "8.1.0",
"author": "Elastic",
"private": true,
"license": "Elastic-License",
diff --git a/x-pack/plugins/apm/ftr_e2e/README.md b/x-pack/plugins/apm/ftr_e2e/README.md
index 2df4e837d2e555..96d6671bb36990 100644
--- a/x-pack/plugins/apm/ftr_e2e/README.md
+++ b/x-pack/plugins/apm/ftr_e2e/README.md
@@ -4,4 +4,4 @@ APM uses [FTR](../../../../packages/kbn-test/README.md) (functional test runner)
## Running tests
-Go to [tests documentation](../scripts/test#e2e-tests-cypress/README.md)
\ No newline at end of file
+Go to [tests documentation](../dev_docs/testing.md#e2e-tests-cypress)
diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/dependencies.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/dependencies.spec.ts
new file mode 100644
index 00000000000000..0ab2d5682a900c
--- /dev/null
+++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/dependencies.spec.ts
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+
+const timeRange = {
+ rangeFrom: Cypress.env('START_DATE'),
+ rangeTo: Cypress.env('END_DATE'),
+};
+
+describe('Dependencies', () => {
+ beforeEach(() => {
+ cy.loginAsReadOnlyUser();
+ });
+
+ describe('top-level dependencies page', () => {
+ it('has a list of dependencies and you can navigate to the page for one', () => {
+ cy.visit(`/app/apm/services?${new URLSearchParams(timeRange)}`);
+ cy.contains('nav a', 'Dependencies').click();
+
+ // `force: true` because Cypress says the element is 0x0
+ cy.contains('postgresql').click({ force: true });
+
+ cy.contains('h1', 'postgresql');
+ });
+ });
+
+ describe('dependency overview page', () => {
+ it('shows dependency information and you can navigate to a page for an upstream service', () => {
+ cy.visit(
+ `/app/apm/backends/overview?${new URLSearchParams({
+ ...timeRange,
+ backendName: 'postgresql',
+ })}`
+ );
+
+ cy.get('[data-test-subj="latencyChart"]');
+ cy.get('[data-test-subj="throughputChart"]');
+ cy.get('[data-test-subj="errorRateChart"]');
+
+ cy.contains('opbeans-python').click({ force: true });
+
+ cy.contains('h1', 'opbeans-python');
+ });
+ });
+
+ describe('service overview page', () => {
+ it('shows dependency information and you can navigate to a page for a dependency', () => {
+ cy.visit(
+ `/app/apm/services/opbeans-python/overview?${new URLSearchParams(
+ timeRange
+ )}`
+ );
+
+ cy.contains('postgresql').click({ force: true });
+
+ cy.contains('h1', 'postgresql');
+ });
+ });
+
+ describe('service dependencies tab', () => {
+ it('shows dependency information and you can navigate to a page for a dependency', () => {
+ cy.visit(
+ `/app/apm/services/opbeans-python/overview?${new URLSearchParams(
+ timeRange
+ )}`
+ );
+
+ cy.contains('a[role="tab"]', 'Dependencies').click();
+
+ cy.contains('Time spent by dependency');
+
+ cy.contains('postgresql').click({ force: true });
+
+ cy.contains('h1', 'postgresql');
+ });
+ });
+});
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/expression_types/embeddable.ts b/x-pack/plugins/canvas/canvas_plugin_src/expression_types/embeddable.ts
index f1ede936c6ace4..ac2e8e8babee1e 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/expression_types/embeddable.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/expression_types/embeddable.ts
@@ -6,11 +6,12 @@
*/
import { ExpressionTypeDefinition } from '../../../../../src/plugins/expressions';
-import { EmbeddableInput } from '../../types';
+import { EmbeddableInput } from '../../../../../src/plugins/embeddable/common/';
import { EmbeddableTypes } from './embeddable_types';
export const EmbeddableExpressionType = 'embeddable';
export { EmbeddableTypes, EmbeddableInput };
+
export interface EmbeddableExpression {
/**
* The type of the expression result
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/index.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/index.ts
index d6d7a0f867849c..2cfdebafb70df4 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/index.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/index.ts
@@ -6,6 +6,7 @@
*/
import { functions as commonFunctions } from '../common';
+import { functions as externalFunctions } from '../external';
import { location } from './location';
import { markdown } from './markdown';
import { urlparam } from './urlparam';
@@ -13,4 +14,13 @@ import { escount } from './escount';
import { esdocs } from './esdocs';
import { essql } from './essql';
-export const functions = [location, markdown, urlparam, escount, esdocs, essql, ...commonFunctions];
+export const functions = [
+ location,
+ markdown,
+ urlparam,
+ escount,
+ esdocs,
+ essql,
+ ...commonFunctions,
+ ...externalFunctions,
+];
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/external/embeddable.test.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/external/embeddable.test.ts
deleted file mode 100644
index 001fb0e3f62e3a..00000000000000
--- a/x-pack/plugins/canvas/canvas_plugin_src/functions/external/embeddable.test.ts
+++ /dev/null
@@ -1,60 +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; you may not use this file except in compliance with the Elastic License
- * 2.0.
- */
-
-import { embeddableFunctionFactory } from './embeddable';
-import { getQueryFilters } from '../../../common/lib/build_embeddable_filters';
-import { ExpressionValueFilter } from '../../../types';
-import { encode } from '../../../common/lib/embeddable_dataurl';
-import { InitializeArguments } from '.';
-
-const filterContext: ExpressionValueFilter = {
- type: 'filter',
- and: [
- {
- type: 'filter',
- and: [],
- value: 'filter-value',
- column: 'filter-column',
- filterType: 'exactly',
- },
- {
- type: 'filter',
- and: [],
- column: 'time-column',
- filterType: 'time',
- from: '2019-06-04T04:00:00.000Z',
- to: '2019-06-05T04:00:00.000Z',
- },
- ],
-};
-
-describe('embeddable', () => {
- const fn = embeddableFunctionFactory({} as InitializeArguments)().fn;
- const config = {
- id: 'some-id',
- timerange: { from: '15m', to: 'now' },
- title: 'test embeddable',
- };
-
- const args = {
- config: encode(config),
- type: 'visualization',
- };
-
- it('accepts null context', () => {
- const expression = fn(null, args, {} as any);
-
- expect(expression.input.filters).toEqual([]);
- });
-
- it('accepts filter context', () => {
- const expression = fn(filterContext, args, {} as any);
- const embeddableFilters = getQueryFilters(filterContext.and);
-
- expect(expression.input.filters).toEqual(embeddableFilters);
- });
-});
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/external/embeddable.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/external/embeddable.ts
deleted file mode 100644
index 7ef8f0a09eb907..00000000000000
--- a/x-pack/plugins/canvas/canvas_plugin_src/functions/external/embeddable.ts
+++ /dev/null
@@ -1,145 +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; you may not use this file except in compliance with the Elastic License
- * 2.0.
- */
-
-import { ExpressionFunctionDefinition } from 'src/plugins/expressions/common';
-import { ExpressionValueFilter, EmbeddableInput } from '../../../types';
-import { EmbeddableExpressionType, EmbeddableExpression } from '../../expression_types';
-import { getFunctionHelp } from '../../../i18n';
-import { SavedObjectReference } from '../../../../../../src/core/types';
-import { getQueryFilters } from '../../../common/lib/build_embeddable_filters';
-import { decode, encode } from '../../../common/lib/embeddable_dataurl';
-import { InitializeArguments } from '.';
-
-export interface Arguments {
- config: string;
- type: string;
-}
-
-const defaultTimeRange = {
- from: 'now-15m',
- to: 'now',
-};
-
-const baseEmbeddableInput = {
- timeRange: defaultTimeRange,
- disableTriggers: true,
- renderMode: 'noInteractivity',
-};
-
-type Return = EmbeddableExpression;
-
-type EmbeddableFunction = ExpressionFunctionDefinition<
- 'embeddable',
- ExpressionValueFilter | null,
- Arguments,
- Return
->;
-
-export function embeddableFunctionFactory({
- embeddablePersistableStateService,
-}: InitializeArguments): () => EmbeddableFunction {
- return function embeddable(): EmbeddableFunction {
- const { help, args: argHelp } = getFunctionHelp().embeddable;
-
- return {
- name: 'embeddable',
- help,
- args: {
- config: {
- aliases: ['_'],
- types: ['string'],
- required: true,
- help: argHelp.config,
- },
- type: {
- types: ['string'],
- required: true,
- help: argHelp.type,
- },
- },
- context: {
- types: ['filter'],
- },
- type: EmbeddableExpressionType,
- fn: (input, args) => {
- const filters = input ? input.and : [];
-
- const embeddableInput = decode(args.config) as EmbeddableInput;
-
- return {
- type: EmbeddableExpressionType,
- input: {
- ...baseEmbeddableInput,
- ...embeddableInput,
- filters: getQueryFilters(filters),
- },
- generatedAt: Date.now(),
- embeddableType: args.type,
- };
- },
-
- extract(state) {
- const input = decode(state.config[0] as string);
-
- // extracts references for by-reference embeddables
- if (input.savedObjectId) {
- const refName = 'embeddable.savedObjectId';
-
- const references: SavedObjectReference[] = [
- {
- name: refName,
- type: state.type[0] as string,
- id: input.savedObjectId as string,
- },
- ];
-
- return {
- state,
- references,
- };
- }
-
- // extracts references for by-value embeddables
- const { state: extractedState, references: extractedReferences } =
- embeddablePersistableStateService.extract({
- ...input,
- type: state.type[0],
- });
-
- const { type, ...extractedInput } = extractedState;
-
- return {
- state: { ...state, config: [encode(extractedInput)], type: [type] },
- references: extractedReferences,
- };
- },
-
- inject(state, references) {
- const input = decode(state.config[0] as string);
- const savedObjectReference = references.find(
- (ref) => ref.name === 'embeddable.savedObjectId'
- );
-
- // injects saved object id for by-references embeddable
- if (savedObjectReference) {
- input.savedObjectId = savedObjectReference.id;
- state.config[0] = encode(input);
- state.type[0] = savedObjectReference.type;
- } else {
- // injects references for by-value embeddables
- const { type, ...injectedInput } = embeddablePersistableStateService.inject(
- { ...input, type: state.type[0] },
- references
- );
- state.config[0] = encode(injectedInput);
- state.type[0] = type;
- }
- return state;
- },
- };
- };
-}
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/external/index.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/external/index.ts
index 1d69e181b5fd9d..407a0e2ebfe05a 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/functions/external/index.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/external/index.ts
@@ -5,26 +5,9 @@
* 2.0.
*/
-import { EmbeddableStart } from 'src/plugins/embeddable/public';
-import { embeddableFunctionFactory } from './embeddable';
import { savedLens } from './saved_lens';
import { savedMap } from './saved_map';
import { savedSearch } from './saved_search';
import { savedVisualization } from './saved_visualization';
-export interface InitializeArguments {
- embeddablePersistableStateService: {
- extract: EmbeddableStart['extract'];
- inject: EmbeddableStart['inject'];
- };
-}
-
-export function initFunctions(initialize: InitializeArguments) {
- return [
- embeddableFunctionFactory(initialize),
- savedLens,
- savedMap,
- savedSearch,
- savedVisualization,
- ];
-}
+export const functions = [savedLens, savedMap, savedVisualization, savedSearch];
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_lens.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_lens.ts
index 67947691f7757c..082a69a874cae2 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_lens.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_lens.ts
@@ -9,8 +9,9 @@ import { ExpressionFunctionDefinition } from 'src/plugins/expressions/common';
import { PaletteOutput } from 'src/plugins/charts/common';
import { Filter as DataFilter } from '@kbn/es-query';
import { TimeRange } from 'src/plugins/data/common';
+import { EmbeddableInput } from 'src/plugins/embeddable/common';
import { getQueryFilters } from '../../../common/lib/build_embeddable_filters';
-import { ExpressionValueFilter, EmbeddableInput, TimeRange as TimeRangeArg } from '../../../types';
+import { ExpressionValueFilter, TimeRange as TimeRangeArg } from '../../../types';
import {
EmbeddableTypes,
EmbeddableExpressionType,
@@ -26,7 +27,7 @@ interface Arguments {
}
export type SavedLensInput = EmbeddableInput & {
- savedObjectId: string;
+ id: string;
timeRange?: TimeRange;
filters: DataFilter[];
palette?: PaletteOutput;
@@ -72,19 +73,18 @@ export function savedLens(): ExpressionFunctionDefinition<
},
},
type: EmbeddableExpressionType,
- fn: (input, { id, timerange, title, palette }) => {
+ fn: (input, args) => {
const filters = input ? input.and : [];
return {
type: EmbeddableExpressionType,
input: {
- id,
- savedObjectId: id,
+ id: args.id,
filters: getQueryFilters(filters),
- timeRange: timerange || defaultTimeRange,
- title: title === null ? undefined : title,
+ timeRange: args.timerange || defaultTimeRange,
+ title: args.title === null ? undefined : args.title,
disableTriggers: true,
- palette,
+ palette: args.palette,
},
embeddableType: EmbeddableTypes.lens,
generatedAt: Date.now(),
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_map.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_map.ts
index a7471c755155c8..538ed3f9198239 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_map.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_map.ts
@@ -30,7 +30,7 @@ const defaultTimeRange = {
to: 'now',
};
-type Output = EmbeddableExpression;
+type Output = EmbeddableExpression;
export function savedMap(): ExpressionFunctionDefinition<
'savedMap',
@@ -85,9 +85,8 @@ export function savedMap(): ExpressionFunctionDefinition<
return {
type: EmbeddableExpressionType,
input: {
- id: args.id,
attributes: { title: '' },
- savedObjectId: args.id,
+ id: args.id,
filters: getQueryFilters(filters),
timeRange: args.timerange || defaultTimeRange,
refreshConfig: {
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_visualization.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_visualization.ts
index 31e3fb2a8c5643..5c0442b43250c8 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_visualization.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_visualization.ts
@@ -25,7 +25,7 @@ interface Arguments {
title: string | null;
}
-type Output = EmbeddableExpression;
+type Output = EmbeddableExpression;
const defaultTimeRange = {
from: 'now-15m',
@@ -94,7 +94,6 @@ export function savedVisualization(): ExpressionFunctionDefinition<
type: EmbeddableExpressionType,
input: {
id,
- savedObjectId: id,
disableTriggers: true,
timeRange: timerange || defaultTimeRange,
filters: getQueryFilters(filters),
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/plugin.ts b/x-pack/plugins/canvas/canvas_plugin_src/plugin.ts
index 591795637aebea..91c573fc4148ba 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/plugin.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/plugin.ts
@@ -7,14 +7,12 @@
import { CoreSetup, CoreStart, Plugin } from 'src/core/public';
import { ChartsPluginStart } from 'src/plugins/charts/public';
-import { PresentationUtilPluginStart } from 'src/plugins/presentation_util/public';
import { CanvasSetup } from '../public';
import { EmbeddableStart } from '../../../../src/plugins/embeddable/public';
import { UiActionsStart } from '../../../../src/plugins/ui_actions/public';
import { Start as InspectorStart } from '../../../../src/plugins/inspector/public';
import { functions } from './functions/browser';
-import { initFunctions } from './functions/external';
import { typeFunctions } from './expression_types';
import { renderFunctions, renderFunctionFactories } from './renderers';
@@ -27,7 +25,6 @@ export interface StartDeps {
uiActions: UiActionsStart;
inspector: InspectorStart;
charts: ChartsPluginStart;
- presentationUtil: PresentationUtilPluginStart;
}
export type SetupInitializer = (core: CoreSetup, plugins: SetupDeps) => T;
@@ -42,13 +39,6 @@ export class CanvasSrcPlugin implements Plugin
plugins.canvas.addRenderers(renderFunctions);
core.getStartServices().then(([coreStart, depsStart]) => {
- const externalFunctions = initFunctions({
- embeddablePersistableStateService: {
- extract: depsStart.embeddable.extract,
- inject: depsStart.embeddable.inject,
- },
- });
- plugins.canvas.addFunctions(externalFunctions);
plugins.canvas.addRenderers(
renderFunctionFactories.map((factory: any) => factory(coreStart, depsStart))
);
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable.tsx b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable.tsx
index 953746c2808406..73e839433c25e0 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable.tsx
+++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable.tsx
@@ -13,17 +13,16 @@ import {
IEmbeddable,
EmbeddableFactory,
EmbeddableFactoryNotFoundError,
- isErrorEmbeddable,
} from '../../../../../../src/plugins/embeddable/public';
import { EmbeddableExpression } from '../../expression_types/embeddable';
import { RendererStrings } from '../../../i18n';
import { embeddableInputToExpression } from './embeddable_input_to_expression';
-import { RendererFactory, EmbeddableInput } from '../../../types';
+import { EmbeddableInput } from '../../expression_types';
+import { RendererFactory } from '../../../types';
import { CANVAS_EMBEDDABLE_CLASSNAME } from '../../../common/lib';
const { embeddable: strings } = RendererStrings;
-// registry of references to embeddables on the workpad
const embeddablesRegistry: {
[key: string]: IEmbeddable | Promise;
} = {};
@@ -31,11 +30,11 @@ const embeddablesRegistry: {
const renderEmbeddableFactory = (core: CoreStart, plugins: StartDeps) => {
const I18nContext = core.i18n.Context;
- return (embeddableObject: IEmbeddable) => {
+ return (embeddableObject: IEmbeddable, domNode: HTMLElement) => {
return (
@@ -57,9 +56,6 @@ export const embeddableRendererFactory = (
reuseDomNode: true,
render: async (domNode, { input, embeddableType }, handlers) => {
const uniqueId = handlers.getElementId();
- const isByValueEnabled = plugins.presentationUtil.labsService.isProjectEnabled(
- 'labs:canvas:byValueEmbeddable'
- );
if (!embeddablesRegistry[uniqueId]) {
const factory = Array.from(plugins.embeddable.getEmbeddableFactories()).find(
@@ -71,27 +67,15 @@ export const embeddableRendererFactory = (
throw new EmbeddableFactoryNotFoundError(embeddableType);
}
- const embeddableInput = { ...input, id: uniqueId };
-
- const embeddablePromise = input.savedObjectId
- ? factory
- .createFromSavedObject(input.savedObjectId, embeddableInput)
- .then((embeddable) => {
- // stores embeddable in registrey
- embeddablesRegistry[uniqueId] = embeddable;
- return embeddable;
- })
- : factory.create(embeddableInput).then((embeddable) => {
- if (!embeddable || isErrorEmbeddable(embeddable)) {
- return;
- }
- // stores embeddable in registry
- embeddablesRegistry[uniqueId] = embeddable as IEmbeddable;
- return embeddable;
- });
- embeddablesRegistry[uniqueId] = embeddablePromise as Promise;
-
- const embeddableObject = (await (async () => embeddablePromise)()) as IEmbeddable;
+ const embeddablePromise = factory
+ .createFromSavedObject(input.id, input)
+ .then((embeddable) => {
+ embeddablesRegistry[uniqueId] = embeddable;
+ return embeddable;
+ });
+ embeddablesRegistry[uniqueId] = embeddablePromise;
+
+ const embeddableObject = await (async () => embeddablePromise)();
const palettes = await plugins.charts.palettes.getPalettes();
@@ -102,8 +86,7 @@ export const embeddableRendererFactory = (
const updatedExpression = embeddableInputToExpression(
updatedInput,
embeddableType,
- palettes,
- isByValueEnabled
+ palettes
);
if (updatedExpression) {
@@ -111,7 +94,15 @@ export const embeddableRendererFactory = (
}
});
- ReactDOM.render(renderEmbeddable(embeddableObject), domNode, () => handlers.done());
+ ReactDOM.render(renderEmbeddable(embeddableObject, domNode), domNode, () =>
+ handlers.done()
+ );
+
+ handlers.onResize(() => {
+ ReactDOM.render(renderEmbeddable(embeddableObject, domNode), domNode, () =>
+ handlers.done()
+ );
+ });
handlers.onDestroy(() => {
subscription.unsubscribe();
@@ -124,7 +115,6 @@ export const embeddableRendererFactory = (
} else {
const embeddable = embeddablesRegistry[uniqueId];
- // updating embeddable input with changes made to expression or filters
if ('updateInput' in embeddable) {
embeddable.updateInput(input);
embeddable.reload();
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable_input_to_expression.ts b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable_input_to_expression.ts
index 80830eac240212..41cefad6a470fa 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable_input_to_expression.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable_input_to_expression.ts
@@ -10,7 +10,6 @@ import { EmbeddableTypes, EmbeddableInput } from '../../expression_types';
import { toExpression as mapToExpression } from './input_type_to_expression/map';
import { toExpression as visualizationToExpression } from './input_type_to_expression/visualization';
import { toExpression as lensToExpression } from './input_type_to_expression/lens';
-import { toExpression as genericToExpression } from './input_type_to_expression/embeddable';
export const inputToExpressionTypeMap = {
[EmbeddableTypes.map]: mapToExpression,
@@ -24,13 +23,8 @@ export const inputToExpressionTypeMap = {
export function embeddableInputToExpression(
input: EmbeddableInput,
embeddableType: string,
- palettes: PaletteRegistry,
- useGenericEmbeddable?: boolean
+ palettes: PaletteRegistry
): string | undefined {
- if (useGenericEmbeddable) {
- return genericToExpression(input, embeddableType);
- }
-
if (inputToExpressionTypeMap[embeddableType]) {
return inputToExpressionTypeMap[embeddableType](input as any, palettes);
}
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/embeddable.test.ts b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/embeddable.test.ts
deleted file mode 100644
index 4b78acec8750ac..00000000000000
--- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/embeddable.test.ts
+++ /dev/null
@@ -1,128 +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; you may not use this file except in compliance with the Elastic License
- * 2.0.
- */
-
-import { toExpression } from './embeddable';
-import { EmbeddableInput } from '../../../../types';
-import { decode } from '../../../../common/lib/embeddable_dataurl';
-import { fromExpression } from '@kbn/interpreter/common';
-
-describe('toExpression', () => {
- describe('by-reference embeddable input', () => {
- const baseEmbeddableInput = {
- id: 'elementId',
- savedObjectId: 'embeddableId',
- filters: [],
- };
-
- it('converts to an embeddable expression', () => {
- const input: EmbeddableInput = baseEmbeddableInput;
-
- const expression = toExpression(input, 'visualization');
- const ast = fromExpression(expression);
-
- expect(ast.type).toBe('expression');
- expect(ast.chain[0].function).toBe('embeddable');
- expect(ast.chain[0].arguments.type[0]).toBe('visualization');
-
- const config = decode(ast.chain[0].arguments.config[0] as string);
-
- expect(config.savedObjectId).toStrictEqual(input.savedObjectId);
- });
-
- it('includes optional input values', () => {
- const input: EmbeddableInput = {
- ...baseEmbeddableInput,
- title: 'title',
- timeRange: {
- from: 'now-1h',
- to: 'now',
- },
- };
-
- const expression = toExpression(input, 'visualization');
- const ast = fromExpression(expression);
-
- const config = decode(ast.chain[0].arguments.config[0] as string);
-
- expect(config).toHaveProperty('title', input.title);
- expect(config).toHaveProperty('timeRange');
- expect(config.timeRange).toHaveProperty('from', input.timeRange?.from);
- expect(config.timeRange).toHaveProperty('to', input.timeRange?.to);
- });
-
- it('includes empty panel title', () => {
- const input: EmbeddableInput = {
- ...baseEmbeddableInput,
- title: '',
- };
-
- const expression = toExpression(input, 'visualization');
- const ast = fromExpression(expression);
-
- const config = decode(ast.chain[0].arguments.config[0] as string);
-
- expect(config).toHaveProperty('title', input.title);
- });
- });
-
- describe('by-value embeddable input', () => {
- const baseEmbeddableInput = {
- id: 'elementId',
- disableTriggers: true,
- filters: [],
- };
- it('converts to an embeddable expression', () => {
- const input: EmbeddableInput = baseEmbeddableInput;
-
- const expression = toExpression(input, 'visualization');
- const ast = fromExpression(expression);
-
- expect(ast.type).toBe('expression');
- expect(ast.chain[0].function).toBe('embeddable');
- expect(ast.chain[0].arguments.type[0]).toBe('visualization');
-
- const config = decode(ast.chain[0].arguments.config[0] as string);
- expect(config.filters).toStrictEqual(input.filters);
- expect(config.disableTriggers).toStrictEqual(input.disableTriggers);
- });
-
- it('includes optional input values', () => {
- const input: EmbeddableInput = {
- ...baseEmbeddableInput,
- title: 'title',
- timeRange: {
- from: 'now-1h',
- to: 'now',
- },
- };
-
- const expression = toExpression(input, 'visualization');
- const ast = fromExpression(expression);
-
- const config = decode(ast.chain[0].arguments.config[0] as string);
-
- expect(config).toHaveProperty('title', input.title);
- expect(config).toHaveProperty('timeRange');
- expect(config.timeRange).toHaveProperty('from', input.timeRange?.from);
- expect(config.timeRange).toHaveProperty('to', input.timeRange?.to);
- });
-
- it('includes empty panel title', () => {
- const input: EmbeddableInput = {
- ...baseEmbeddableInput,
- title: '',
- };
-
- const expression = toExpression(input, 'visualization');
- const ast = fromExpression(expression);
-
- const config = decode(ast.chain[0].arguments.config[0] as string);
-
- expect(config).toHaveProperty('title', input.title);
- });
- });
-});
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/embeddable.ts b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/embeddable.ts
deleted file mode 100644
index 94d86f6640be1d..00000000000000
--- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/embeddable.ts
+++ /dev/null
@@ -1,13 +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; you may not use this file except in compliance with the Elastic License
- * 2.0.
- */
-
-import { encode } from '../../../../common/lib/embeddable_dataurl';
-import { EmbeddableInput } from '../../../expression_types';
-
-export function toExpression(input: EmbeddableInput, embeddableType: string): string {
- return `embeddable config="${encode(input)}" type="${embeddableType}"`;
-}
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/lens.test.ts b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/lens.test.ts
index 224cdfba389d77..24da7238bcee94 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/lens.test.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/lens.test.ts
@@ -11,8 +11,7 @@ import { fromExpression, Ast } from '@kbn/interpreter/common';
import { chartPluginMock } from 'src/plugins/charts/public/mocks';
const baseEmbeddableInput = {
- id: 'elementId',
- savedObjectId: 'embeddableId',
+ id: 'embeddableId',
filters: [],
};
@@ -28,7 +27,7 @@ describe('toExpression', () => {
expect(ast.type).toBe('expression');
expect(ast.chain[0].function).toBe('savedLens');
- expect(ast.chain[0].arguments.id).toStrictEqual([input.savedObjectId]);
+ expect(ast.chain[0].arguments.id).toStrictEqual([input.id]);
expect(ast.chain[0].arguments).not.toHaveProperty('title');
expect(ast.chain[0].arguments).not.toHaveProperty('timerange');
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/lens.ts b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/lens.ts
index 5a13b73b3fe746..35e106f234fa4e 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/lens.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/lens.ts
@@ -14,7 +14,7 @@ export function toExpression(input: SavedLensInput, palettes: PaletteRegistry):
expressionParts.push('savedLens');
- expressionParts.push(`id="${input.savedObjectId}"`);
+ expressionParts.push(`id="${input.id}"`);
if (input.title !== undefined) {
expressionParts.push(`title="${input.title}"`);
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/map.test.ts b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/map.test.ts
index af7b40a9b283d9..804d0d849cc7f7 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/map.test.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/map.test.ts
@@ -6,12 +6,12 @@
*/
import { toExpression } from './map';
+import { MapEmbeddableInput } from '../../../../../../plugins/maps/public/embeddable';
import { fromExpression, Ast } from '@kbn/interpreter/common';
const baseSavedMapInput = {
- id: 'elementId',
attributes: { title: '' },
- savedObjectId: 'embeddableId',
+ id: 'embeddableId',
filters: [],
isLayerTOCOpen: false,
refreshConfig: {
@@ -23,7 +23,7 @@ const baseSavedMapInput = {
describe('toExpression', () => {
it('converts to a savedMap expression', () => {
- const input = {
+ const input: MapEmbeddableInput = {
...baseSavedMapInput,
};
@@ -33,7 +33,7 @@ describe('toExpression', () => {
expect(ast.type).toBe('expression');
expect(ast.chain[0].function).toBe('savedMap');
- expect(ast.chain[0].arguments.id).toStrictEqual([input.savedObjectId]);
+ expect(ast.chain[0].arguments.id).toStrictEqual([input.id]);
expect(ast.chain[0].arguments).not.toHaveProperty('title');
expect(ast.chain[0].arguments).not.toHaveProperty('center');
@@ -41,7 +41,7 @@ describe('toExpression', () => {
});
it('includes optional input values', () => {
- const input = {
+ const input: MapEmbeddableInput = {
...baseSavedMapInput,
mapCenter: {
lat: 1,
@@ -73,7 +73,7 @@ describe('toExpression', () => {
});
it('includes empty panel title', () => {
- const input = {
+ const input: MapEmbeddableInput = {
...baseSavedMapInput,
title: '',
};
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/map.ts b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/map.ts
index 03746f38b4696c..3fd6a68a327c60 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/map.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/map.ts
@@ -5,14 +5,13 @@
* 2.0.
*/
-import { MapEmbeddableInput } from '../../../../../../plugins/maps/public';
+import { MapEmbeddableInput } from '../../../../../../plugins/maps/public/embeddable';
-export function toExpression(input: MapEmbeddableInput & { savedObjectId: string }): string {
+export function toExpression(input: MapEmbeddableInput): string {
const expressionParts = [] as string[];
expressionParts.push('savedMap');
-
- expressionParts.push(`id="${input.savedObjectId}"`);
+ expressionParts.push(`id="${input.id}"`);
if (input.title !== undefined) {
expressionParts.push(`title="${input.title}"`);
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/visualization.test.ts b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/visualization.test.ts
index 4c61a130f3c95f..c5106b9a102b40 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/visualization.test.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/visualization.test.ts
@@ -9,8 +9,7 @@ import { toExpression } from './visualization';
import { fromExpression, Ast } from '@kbn/interpreter/common';
const baseInput = {
- id: 'elementId',
- savedObjectId: 'embeddableId',
+ id: 'embeddableId',
};
describe('toExpression', () => {
@@ -25,7 +24,7 @@ describe('toExpression', () => {
expect(ast.type).toBe('expression');
expect(ast.chain[0].function).toBe('savedVisualization');
- expect(ast.chain[0].arguments.id).toStrictEqual([input.savedObjectId]);
+ expect(ast.chain[0].arguments.id).toStrictEqual([input.id]);
});
it('includes timerange if given', () => {
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/visualization.ts b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/visualization.ts
index 364d7cd0755db4..bcb73b2081fee5 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/visualization.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/input_type_to_expression/visualization.ts
@@ -7,11 +7,11 @@
import { VisualizeInput } from 'src/plugins/visualizations/public';
-export function toExpression(input: VisualizeInput & { savedObjectId: string }): string {
+export function toExpression(input: VisualizeInput): string {
const expressionParts = [] as string[];
expressionParts.push('savedVisualization');
- expressionParts.push(`id="${input.savedObjectId}"`);
+ expressionParts.push(`id="${input.id}"`);
if (input.title !== undefined) {
expressionParts.push(`title="${input.title}"`);
diff --git a/x-pack/plugins/canvas/common/lib/embeddable_dataurl.ts b/x-pack/plugins/canvas/common/lib/embeddable_dataurl.ts
deleted file mode 100644
index e76dedfe63b14a..00000000000000
--- a/x-pack/plugins/canvas/common/lib/embeddable_dataurl.ts
+++ /dev/null
@@ -1,13 +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; you may not use this file except in compliance with the Elastic License
- * 2.0.
- */
-
-import { EmbeddableInput } from '../../types';
-
-export const encode = (input: Partial) =>
- Buffer.from(JSON.stringify(input)).toString('base64');
-export const decode = (serializedInput: string) =>
- JSON.parse(Buffer.from(serializedInput, 'base64').toString());
diff --git a/x-pack/plugins/canvas/i18n/functions/dict/embeddable.ts b/x-pack/plugins/canvas/i18n/functions/dict/embeddable.ts
deleted file mode 100644
index 279f58799e8c00..00000000000000
--- a/x-pack/plugins/canvas/i18n/functions/dict/embeddable.ts
+++ /dev/null
@@ -1,25 +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; you may not use this file except in compliance with the Elastic License
- * 2.0.
- */
-
-import { i18n } from '@kbn/i18n';
-import { embeddableFunctionFactory } from '../../../canvas_plugin_src/functions/external/embeddable';
-import { FunctionHelp } from '../function_help';
-import { FunctionFactory } from '../../../types';
-
-export const help: FunctionHelp>> = {
- help: i18n.translate('xpack.canvas.functions.embeddableHelpText', {
- defaultMessage: `Returns an embeddable with the provided configuration`,
- }),
- args: {
- config: i18n.translate('xpack.canvas.functions.embeddable.args.idHelpText', {
- defaultMessage: `The base64 encoded embeddable input object`,
- }),
- type: i18n.translate('xpack.canvas.functions.embeddable.args.typeHelpText', {
- defaultMessage: `The embeddable type`,
- }),
- },
-};
diff --git a/x-pack/plugins/canvas/i18n/functions/function_help.ts b/x-pack/plugins/canvas/i18n/functions/function_help.ts
index 520d32af1c272c..5eae785fefa2ea 100644
--- a/x-pack/plugins/canvas/i18n/functions/function_help.ts
+++ b/x-pack/plugins/canvas/i18n/functions/function_help.ts
@@ -27,7 +27,6 @@ import { help as demodata } from './dict/demodata';
import { help as doFn } from './dict/do';
import { help as dropdownControl } from './dict/dropdown_control';
import { help as eq } from './dict/eq';
-import { help as embeddable } from './dict/embeddable';
import { help as escount } from './dict/escount';
import { help as esdocs } from './dict/esdocs';
import { help as essql } from './dict/essql';
@@ -183,7 +182,6 @@ export const getFunctionHelp = (): FunctionHelpDict => ({
do: doFn,
dropdownControl,
eq,
- embeddable,
escount,
esdocs,
essql,
diff --git a/x-pack/plugins/canvas/kibana.json b/x-pack/plugins/canvas/kibana.json
index 2fd312502a3c74..9c4d1b2179d821 100644
--- a/x-pack/plugins/canvas/kibana.json
+++ b/x-pack/plugins/canvas/kibana.json
@@ -25,7 +25,6 @@
"features",
"inspector",
"presentationUtil",
- "visualizations",
"uiActions",
"share"
],
diff --git a/x-pack/plugins/canvas/public/components/embeddable_flyout/flyout.component.tsx b/x-pack/plugins/canvas/public/components/embeddable_flyout/flyout.component.tsx
index 57f52fcf21f0f9..bf731876bf8c88 100644
--- a/x-pack/plugins/canvas/public/components/embeddable_flyout/flyout.component.tsx
+++ b/x-pack/plugins/canvas/public/components/embeddable_flyout/flyout.component.tsx
@@ -5,7 +5,7 @@
* 2.0.
*/
-import React, { FC, useCallback } from 'react';
+import React, { FC } from 'react';
import { EuiFlyout, EuiFlyoutHeader, EuiFlyoutBody, EuiTitle } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
@@ -27,44 +27,38 @@ const strings = {
};
export interface Props {
onClose: () => void;
- onSelect: (id: string, embeddableType: string, isByValueEnabled?: boolean) => void;
+ onSelect: (id: string, embeddableType: string) => void;
availableEmbeddables: string[];
- isByValueEnabled?: boolean;
}
-export const AddEmbeddableFlyout: FC = ({
- onSelect,
- availableEmbeddables,
- onClose,
- isByValueEnabled,
-}) => {
+export const AddEmbeddableFlyout: FC = ({ onSelect, availableEmbeddables, onClose }) => {
const embeddablesService = useEmbeddablesService();
const platformService = usePlatformService();
const { getEmbeddableFactories } = embeddablesService;
const { getSavedObjects, getUISettings } = platformService;
- const onAddPanel = useCallback(
- (id: string, savedObjectType: string) => {
- const embeddableFactories = getEmbeddableFactories();
- // Find the embeddable type from the saved object type
- const found = Array.from(embeddableFactories).find((embeddableFactory) => {
- return Boolean(
- embeddableFactory.savedObjectMetaData &&
- embeddableFactory.savedObjectMetaData.type === savedObjectType
- );
- });
+ const onAddPanel = (id: string, savedObjectType: string, name: string) => {
+ const embeddableFactories = getEmbeddableFactories();
- const foundEmbeddableType = found ? found.type : 'unknown';
+ // Find the embeddable type from the saved object type
+ const found = Array.from(embeddableFactories).find((embeddableFactory) => {
+ return Boolean(
+ embeddableFactory.savedObjectMetaData &&
+ embeddableFactory.savedObjectMetaData.type === savedObjectType
+ );
+ });
- onSelect(id, foundEmbeddableType, isByValueEnabled);
- },
- [isByValueEnabled, getEmbeddableFactories, onSelect]
- );
+ const foundEmbeddableType = found ? found.type : 'unknown';
+
+ onSelect(id, foundEmbeddableType);
+ };
const embeddableFactories = getEmbeddableFactories();
const availableSavedObjects = Array.from(embeddableFactories)
- .filter((factory) => isByValueEnabled || availableEmbeddables.includes(factory.type))
+ .filter((factory) => {
+ return availableEmbeddables.includes(factory.type);
+ })
.map((factory) => factory.savedObjectMetaData)
.filter>(function (
maybeSavedObjectMetaData
diff --git a/x-pack/plugins/canvas/public/components/embeddable_flyout/flyout.tsx b/x-pack/plugins/canvas/public/components/embeddable_flyout/flyout.tsx
index 4dc8d963932d8f..770a4cac606b0b 100644
--- a/x-pack/plugins/canvas/public/components/embeddable_flyout/flyout.tsx
+++ b/x-pack/plugins/canvas/public/components/embeddable_flyout/flyout.tsx
@@ -8,14 +8,12 @@
import React, { useMemo, useEffect, useCallback } from 'react';
import { createPortal } from 'react-dom';
import { useSelector, useDispatch } from 'react-redux';
-import { encode } from '../../../common/lib/embeddable_dataurl';
import { AddEmbeddableFlyout as Component, Props as ComponentProps } from './flyout.component';
// @ts-expect-error untyped local
import { addElement } from '../../state/actions/elements';
import { getSelectedPage } from '../../state/selectors/workpad';
import { EmbeddableTypes } from '../../../canvas_plugin_src/expression_types/embeddable';
import { State } from '../../../types';
-import { useLabsService } from '../../services';
const allowedEmbeddables = {
[EmbeddableTypes.map]: (id: string) => {
@@ -67,9 +65,6 @@ export const AddEmbeddablePanel: React.FunctionComponent = ({
availableEmbeddables,
...restProps
}) => {
- const labsService = useLabsService();
- const isByValueEnabled = labsService.isProjectEnabled('labs:canvas:byValueEmbeddable');
-
const dispatch = useDispatch();
const pageId = useSelector((state) => getSelectedPage(state));
@@ -79,27 +74,18 @@ export const AddEmbeddablePanel: React.FunctionComponent = ({
);
const onSelect = useCallback(
- (id: string, type: string): void => {
+ (id: string, type: string) => {
const partialElement = {
expression: `markdown "Could not find embeddable for type ${type}" | render`,
};
-
- // If by-value is enabled, we'll handle both by-reference and by-value embeddables
- // with the new generic `embeddable` function.
- // Otherwise we fallback to the embeddable type specific expressions.
- if (isByValueEnabled) {
- const config = encode({ savedObjectId: id });
- partialElement.expression = `embeddable config="${config}"
- type="${type}"
-| render`;
- } else if (allowedEmbeddables[type]) {
+ if (allowedEmbeddables[type]) {
partialElement.expression = allowedEmbeddables[type](id);
}
addEmbeddable(pageId, partialElement);
restProps.onClose();
},
- [addEmbeddable, pageId, restProps, isByValueEnabled]
+ [addEmbeddable, pageId, restProps]
);
return (
@@ -107,7 +93,6 @@ export const AddEmbeddablePanel: React.FunctionComponent = ({
{...restProps}
availableEmbeddables={availableEmbeddables || []}
onSelect={onSelect}
- isByValueEnabled={isByValueEnabled}
/>
);
};
diff --git a/x-pack/plugins/canvas/public/components/hooks/workpad/index.tsx b/x-pack/plugins/canvas/public/components/hooks/workpad/index.tsx
index ffd5b095b12e52..50d527036560ad 100644
--- a/x-pack/plugins/canvas/public/components/hooks/workpad/index.tsx
+++ b/x-pack/plugins/canvas/public/components/hooks/workpad/index.tsx
@@ -6,5 +6,3 @@
*/
export { useDownloadWorkpad, useDownloadRenderedWorkpad } from './use_download_workpad';
-
-export { useIncomingEmbeddable } from './use_incoming_embeddable';
diff --git a/x-pack/plugins/canvas/public/components/hooks/workpad/use_incoming_embeddable.ts b/x-pack/plugins/canvas/public/components/hooks/workpad/use_incoming_embeddable.ts
deleted file mode 100644
index 2f8e2503ea57ef..00000000000000
--- a/x-pack/plugins/canvas/public/components/hooks/workpad/use_incoming_embeddable.ts
+++ /dev/null
@@ -1,86 +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; you may not use this file except in compliance with the Elastic License
- * 2.0.
- */
-
-import { useEffect } from 'react';
-import { useDispatch } from 'react-redux';
-import { fromExpression } from '@kbn/interpreter/common';
-import { CANVAS_APP } from '../../../../common/lib';
-import { decode, encode } from '../../../../common/lib/embeddable_dataurl';
-import { CanvasElement, CanvasPage } from '../../../../types';
-import { useEmbeddablesService, useLabsService } from '../../../services';
-// @ts-expect-error unconverted file
-import { addElement } from '../../../state/actions/elements';
-// @ts-expect-error unconverted file
-import { selectToplevelNodes } from '../../../state/actions/transient';
-
-import {
- updateEmbeddableExpression,
- fetchEmbeddableRenderable,
-} from '../../../state/actions/embeddable';
-import { clearValue } from '../../../state/actions/resolved_args';
-
-export const useIncomingEmbeddable = (selectedPage: CanvasPage) => {
- const embeddablesService = useEmbeddablesService();
- const labsService = useLabsService();
- const dispatch = useDispatch();
- const isByValueEnabled = labsService.isProjectEnabled('labs:canvas:byValueEmbeddable');
- const stateTransferService = embeddablesService.getStateTransfer();
-
- // fetch incoming embeddable from state transfer service.
- const incomingEmbeddable = stateTransferService.getIncomingEmbeddablePackage(CANVAS_APP, true);
-
- useEffect(() => {
- if (isByValueEnabled && incomingEmbeddable) {
- const { embeddableId, input: incomingInput, type } = incomingEmbeddable;
-
- // retrieve existing element
- const originalElement = selectedPage.elements.find(
- ({ id }: CanvasElement) => id === embeddableId
- );
-
- if (originalElement) {
- const originalAst = fromExpression(originalElement!.expression);
-
- const functionIndex = originalAst.chain.findIndex(
- ({ function: fn }) => fn === 'embeddable'
- );
-
- const originalInput = decode(
- originalAst.chain[functionIndex].arguments.config[0] as string
- );
-
- // clear out resolved arg for old embeddable
- const argumentPath = [embeddableId, 'expressionRenderable'];
- dispatch(clearValue({ path: argumentPath }));
-
- const updatedInput = { ...originalInput, ...incomingInput };
-
- const expression = `embeddable config="${encode(updatedInput)}"
- type="${type}"
-| render`;
-
- dispatch(
- updateEmbeddableExpression({
- elementId: originalElement.id,
- embeddableExpression: expression,
- })
- );
-
- // update resolved args
- dispatch(fetchEmbeddableRenderable(originalElement.id));
-
- // select new embeddable element
- dispatch(selectToplevelNodes([embeddableId]));
- } else {
- const expression = `embeddable config="${encode(incomingInput)}"
- type="${type}"
-| render`;
- dispatch(addElement(selectedPage.id, { expression }));
- }
- }
- }, [dispatch, selectedPage, incomingEmbeddable, isByValueEnabled]);
-};
diff --git a/x-pack/plugins/canvas/public/components/workpad/workpad.tsx b/x-pack/plugins/canvas/public/components/workpad/workpad.tsx
index 7cc077203c7372..622c885b6ef281 100644
--- a/x-pack/plugins/canvas/public/components/workpad/workpad.tsx
+++ b/x-pack/plugins/canvas/public/components/workpad/workpad.tsx
@@ -27,7 +27,6 @@ import { WorkpadRoutingContext } from '../../routes/workpad';
import { usePlatformService } from '../../services';
import { Workpad as WorkpadComponent, Props } from './workpad.component';
import { State } from '../../../types';
-import { useIncomingEmbeddable } from '../hooks';
type ContainerProps = Pick;
@@ -59,9 +58,6 @@ export const Workpad: FC = (props) => {
};
});
- const selectedPage = propsFromState.pages[propsFromState.selectedPageNumber - 1];
- useIncomingEmbeddable(selectedPage);
-
const fetchAllRenderables = useCallback(() => {
dispatch(fetchAllRenderablesAction());
}, [dispatch]);
diff --git a/x-pack/plugins/canvas/public/components/workpad_app/workpad_app.scss b/x-pack/plugins/canvas/public/components/workpad_app/workpad_app.scss
index 0ddd44ed8f9a81..4acdca10d61cc2 100644
--- a/x-pack/plugins/canvas/public/components/workpad_app/workpad_app.scss
+++ b/x-pack/plugins/canvas/public/components/workpad_app/workpad_app.scss
@@ -31,7 +31,7 @@ $canvasLayoutFontSize: $euiFontSizeS;
.canvasLayout__stageHeader {
flex-grow: 0;
flex-basis: auto;
- padding: $euiSizeS $euiSize;
+ padding: $euiSizeS;
font-size: $canvasLayoutFontSize;
border-bottom: $euiBorderThin;
background: $euiColorLightestShade;
diff --git a/x-pack/plugins/canvas/public/components/workpad_header/editor_menu/__stories__/__snapshots__/editor_menu.stories.storyshot b/x-pack/plugins/canvas/public/components/workpad_header/editor_menu/__stories__/__snapshots__/editor_menu.stories.storyshot
deleted file mode 100644
index f4aab0e59e7ee6..00000000000000
--- a/x-pack/plugins/canvas/public/components/workpad_header/editor_menu/__stories__/__snapshots__/editor_menu.stories.storyshot
+++ /dev/null
@@ -1,81 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`Storyshots components/WorkpadHeader/EditorMenu dark mode 1`] = `
-
-
-
-
-
-`;
-
-exports[`Storyshots components/WorkpadHeader/EditorMenu default 1`] = `
-
-
-
-
-
-`;
diff --git a/x-pack/plugins/canvas/public/components/workpad_header/editor_menu/__stories__/editor_menu.stories.tsx b/x-pack/plugins/canvas/public/components/workpad_header/editor_menu/__stories__/editor_menu.stories.tsx
deleted file mode 100644
index 01048bc0af3010..00000000000000
--- a/x-pack/plugins/canvas/public/components/workpad_header/editor_menu/__stories__/editor_menu.stories.tsx
+++ /dev/null
@@ -1,107 +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; you may not use this file except in compliance with the Elastic License
- * 2.0.
- */
-
-import { storiesOf } from '@storybook/react';
-import { action } from '@storybook/addon-actions';
-import React from 'react';
-import { EmbeddableFactoryDefinition, IEmbeddable } from 'src/plugins/embeddable/public';
-import { BaseVisType, VisTypeAlias } from 'src/plugins/visualizations/public';
-import { EditorMenu } from '../editor_menu.component';
-
-const testFactories: EmbeddableFactoryDefinition[] = [
- {
- type: 'ml_anomaly_swimlane',
- getDisplayName: () => 'Anomaly swimlane',
- getIconType: () => '',
- getDescription: () => 'Description for anomaly swimlane',
- isEditable: () => Promise.resolve(true),
- create: () => Promise.resolve({ id: 'swimlane_embeddable' } as IEmbeddable),
- grouping: [
- {
- id: 'ml',
- getDisplayName: () => 'machine learning',
- getIconType: () => 'machineLearningApp',
- },
- ],
- },
- {
- type: 'ml_anomaly_chart',
- getDisplayName: () => 'Anomaly chart',
- getIconType: () => '',
- getDescription: () => 'Description for anomaly chart',
- isEditable: () => Promise.resolve(true),
- create: () => Promise.resolve({ id: 'anomaly_chart_embeddable' } as IEmbeddable),
- grouping: [
- {
- id: 'ml',
- getDisplayName: () => 'machine learning',
- getIconType: () => 'machineLearningApp',
- },
- ],
- },
- {
- type: 'log_stream',
- getDisplayName: () => 'Log stream',
- getIconType: () => '',
- getDescription: () => 'Description for log stream',
- isEditable: () => Promise.resolve(true),
- create: () => Promise.resolve({ id: 'anomaly_chart_embeddable' } as IEmbeddable),
- },
-];
-
-const testVisTypes: BaseVisType[] = [
- { title: 'TSVB', icon: '', description: 'Description of TSVB', name: 'tsvb' } as BaseVisType,
- {
- titleInWizard: 'Custom visualization',
- title: 'Vega',
- icon: '',
- description: 'Description of Vega',
- name: 'vega',
- } as BaseVisType,
-];
-
-const testVisTypeAliases: VisTypeAlias[] = [
- {
- title: 'Lens',
- aliasApp: 'lens',
- aliasPath: 'path/to/lens',
- icon: 'lensApp',
- name: 'lens',
- description: 'Description of Lens app',
- stage: 'production',
- },
- {
- title: 'Maps',
- aliasApp: 'maps',
- aliasPath: 'path/to/maps',
- icon: 'gisApp',
- name: 'maps',
- description: 'Description of Maps app',
- stage: 'production',
- },
-];
-
-storiesOf('components/WorkpadHeader/EditorMenu', module)
- .add('default', () => (
- action('createNewVisType')}
- createNewEmbeddable={() => action('createNewEmbeddable')}
- />
- ))
- .add('dark mode', () => (
- action('createNewVisType')}
- createNewEmbeddable={() => action('createNewEmbeddable')}
- />
- ));
diff --git a/x-pack/plugins/canvas/public/components/workpad_header/editor_menu/editor_menu.component.tsx b/x-pack/plugins/canvas/public/components/workpad_header/editor_menu/editor_menu.component.tsx
deleted file mode 100644
index e8f762f9731a19..00000000000000
--- a/x-pack/plugins/canvas/public/components/workpad_header/editor_menu/editor_menu.component.tsx
+++ /dev/null
@@ -1,170 +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; you may not use this file except in compliance with the Elastic License
- * 2.0.
- */
-
-import React, { FC } from 'react';
-import {
- EuiContextMenu,
- EuiContextMenuPanelItemDescriptor,
- EuiContextMenuItemIcon,
-} from '@elastic/eui';
-import { i18n } from '@kbn/i18n';
-import { EmbeddableFactoryDefinition } from '../../../../../../../src/plugins/embeddable/public';
-import { BaseVisType, VisTypeAlias } from '../../../../../../../src/plugins/visualizations/public';
-import { SolutionToolbarPopover } from '../../../../../../../src/plugins/presentation_util/public';
-
-const strings = {
- getEditorMenuButtonLabel: () =>
- i18n.translate('xpack.canvas.solutionToolbar.editorMenuButtonLabel', {
- defaultMessage: 'Select type',
- }),
-};
-
-interface FactoryGroup {
- id: string;
- appName: string;
- icon: EuiContextMenuItemIcon;
- panelId: number;
- factories: EmbeddableFactoryDefinition[];
-}
-
-interface Props {
- factories: EmbeddableFactoryDefinition[];
- isDarkThemeEnabled?: boolean;
- promotedVisTypes: BaseVisType[];
- visTypeAliases: VisTypeAlias[];
- createNewVisType: (visType?: BaseVisType | VisTypeAlias) => () => void;
- createNewEmbeddable: (factory: EmbeddableFactoryDefinition) => () => void;
-}
-
-export const EditorMenu: FC = ({
- factories,
- isDarkThemeEnabled,
- promotedVisTypes,
- visTypeAliases,
- createNewVisType,
- createNewEmbeddable,
-}: Props) => {
- const factoryGroupMap: Record = {};
- const ungroupedFactories: EmbeddableFactoryDefinition[] = [];
-
- let panelCount = 1;
-
- // Maps factories with a group to create nested context menus for each group type
- // and pushes ungrouped factories into a separate array
- factories.forEach((factory: EmbeddableFactoryDefinition, index) => {
- const { grouping } = factory;
-
- if (grouping) {
- grouping.forEach((group) => {
- if (factoryGroupMap[group.id]) {
- factoryGroupMap[group.id].factories.push(factory);
- } else {
- factoryGroupMap[group.id] = {
- id: group.id,
- appName: group.getDisplayName ? group.getDisplayName({}) : group.id,
- icon: (group.getIconType ? group.getIconType({}) : 'empty') as EuiContextMenuItemIcon,
- factories: [factory],
- panelId: panelCount,
- };
-
- panelCount++;
- }
- });
- } else {
- ungroupedFactories.push(factory);
- }
- });
-
- const getVisTypeMenuItem = (visType: BaseVisType): EuiContextMenuPanelItemDescriptor => {
- const { name, title, titleInWizard, description, icon = 'empty' } = visType;
- return {
- name: titleInWizard || title,
- icon: icon as string,
- onClick: createNewVisType(visType),
- 'data-test-subj': `visType-${name}`,
- toolTipContent: description,
- };
- };
-
- const getVisTypeAliasMenuItem = (
- visTypeAlias: VisTypeAlias
- ): EuiContextMenuPanelItemDescriptor => {
- const { name, title, description, icon = 'empty' } = visTypeAlias;
-
- return {
- name: title,
- icon,
- onClick: createNewVisType(visTypeAlias),
- 'data-test-subj': `visType-${name}`,
- toolTipContent: description,
- };
- };
-
- const getEmbeddableFactoryMenuItem = (
- factory: EmbeddableFactoryDefinition
- ): EuiContextMenuPanelItemDescriptor => {
- const icon = factory?.getIconType ? factory.getIconType() : 'empty';
-
- const toolTipContent = factory?.getDescription ? factory.getDescription() : undefined;
-
- return {
- name: factory.getDisplayName(),
- icon,
- toolTipContent,
- onClick: createNewEmbeddable(factory),
- 'data-test-subj': `createNew-${factory.type}`,
- };
- };
-
- const editorMenuPanels = [
- {
- id: 0,
- items: [
- ...visTypeAliases.map(getVisTypeAliasMenuItem),
- ...Object.values(factoryGroupMap).map(({ id, appName, icon, panelId }) => ({
- name: appName,
- icon,
- panel: panelId,
- 'data-test-subj': `canvasEditorMenu-${id}Group`,
- })),
- ...ungroupedFactories.map(getEmbeddableFactoryMenuItem),
- ...promotedVisTypes.map(getVisTypeMenuItem),
- ],
- },
- ...Object.values(factoryGroupMap).map(
- ({ appName, panelId, factories: groupFactories }: FactoryGroup) => ({
- id: panelId,
- title: appName,
- items: groupFactories.map(getEmbeddableFactoryMenuItem),
- })
- ),
- ];
-
- return (
-
- {() => (
-
- )}
-
- );
-};
diff --git a/x-pack/plugins/canvas/public/components/workpad_header/editor_menu/editor_menu.tsx b/x-pack/plugins/canvas/public/components/workpad_header/editor_menu/editor_menu.tsx
deleted file mode 100644
index dad34e6983c5db..00000000000000
--- a/x-pack/plugins/canvas/public/components/workpad_header/editor_menu/editor_menu.tsx
+++ /dev/null
@@ -1,147 +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; you may not use this file except in compliance with the Elastic License
- * 2.0.
- */
-
-import React, { FC, useCallback } from 'react';
-import { useLocation } from 'react-router-dom';
-import { trackCanvasUiMetric, METRIC_TYPE } from '../../../../public/lib/ui_metric';
-import {
- useEmbeddablesService,
- usePlatformService,
- useVisualizationsService,
-} from '../../../services';
-import {
- BaseVisType,
- VisGroups,
- VisTypeAlias,
-} from '../../../../../../../src/plugins/visualizations/public';
-import {
- EmbeddableFactoryDefinition,
- EmbeddableInput,
-} from '../../../../../../../src/plugins/embeddable/public';
-import { CANVAS_APP } from '../../../../common/lib';
-import { encode } from '../../../../common/lib/embeddable_dataurl';
-import { ElementSpec } from '../../../../types';
-import { EditorMenu as Component } from './editor_menu.component';
-
-interface Props {
- /**
- * Handler for adding a selected element to the workpad
- */
- addElement: (element: Partial) => void;
-}
-
-export const EditorMenu: FC = ({ addElement }) => {
- const embeddablesService = useEmbeddablesService();
- const { pathname, search } = useLocation();
- const platformService = usePlatformService();
- const stateTransferService = embeddablesService.getStateTransfer();
- const visualizationsService = useVisualizationsService();
- const IS_DARK_THEME = platformService.getUISetting('theme:darkMode');
-
- const createNewVisType = useCallback(
- (visType?: BaseVisType | VisTypeAlias) => () => {
- let path = '';
- let appId = '';
-
- if (visType) {
- if (trackCanvasUiMetric) {
- trackCanvasUiMetric(METRIC_TYPE.CLICK, `${visType.name}:create`);
- }
-
- if ('aliasPath' in visType) {
- appId = visType.aliasApp;
- path = visType.aliasPath;
- } else {
- appId = 'visualize';
- path = `#/create?type=${encodeURIComponent(visType.name)}`;
- }
- } else {
- appId = 'visualize';
- path = '#/create?';
- }
-
- stateTransferService.navigateToEditor(appId, {
- path,
- state: {
- originatingApp: CANVAS_APP,
- originatingPath: `#/${pathname}${search}`,
- },
- });
- },
- [stateTransferService, pathname, search]
- );
-
- const createNewEmbeddable = useCallback(
- (factory: EmbeddableFactoryDefinition) => async () => {
- if (trackCanvasUiMetric) {
- trackCanvasUiMetric(METRIC_TYPE.CLICK, factory.type);
- }
- let embeddableInput;
- if (factory.getExplicitInput) {
- embeddableInput = await factory.getExplicitInput();
- } else {
- const newEmbeddable = await factory.create({} as EmbeddableInput);
- embeddableInput = newEmbeddable?.getInput();
- }
-
- if (embeddableInput) {
- const config = encode(embeddableInput);
- const expression = `embeddable config="${config}"
- type="${factory.type}"
-| render`;
-
- addElement({ expression });
- }
- },
- [addElement]
- );
-
- const getVisTypesByGroup = (group: VisGroups): BaseVisType[] =>
- visualizationsService
- .getByGroup(group)
- .sort(({ name: a }: BaseVisType | VisTypeAlias, { name: b }: BaseVisType | VisTypeAlias) => {
- if (a < b) {
- return -1;
- }
- if (a > b) {
- return 1;
- }
- return 0;
- })
- .filter(({ hidden }: BaseVisType) => !hidden);
-
- const visTypeAliases = visualizationsService
- .getAliases()
- .sort(({ promotion: a = false }: VisTypeAlias, { promotion: b = false }: VisTypeAlias) =>
- a === b ? 0 : a ? -1 : 1
- );
-
- const factories = embeddablesService
- ? Array.from(embeddablesService.getEmbeddableFactories()).filter(
- ({ type, isEditable, canCreateNew, isContainerType }) =>
- isEditable() &&
- !isContainerType &&
- canCreateNew() &&
- !['visualization', 'ml'].some((factoryType) => {
- return type.includes(factoryType);
- })
- )
- : [];
-
- const promotedVisTypes = getVisTypesByGroup(VisGroups.PROMOTED);
-
- return (
-
- );
-};
diff --git a/x-pack/plugins/canvas/public/components/workpad_header/editor_menu/index.ts b/x-pack/plugins/canvas/public/components/workpad_header/editor_menu/index.ts
deleted file mode 100644
index 0f903b1bbbe2ed..00000000000000
--- a/x-pack/plugins/canvas/public/components/workpad_header/editor_menu/index.ts
+++ /dev/null
@@ -1,9 +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; you may not use this file except in compliance with the Elastic License
- * 2.0.
- */
-
-export { EditorMenu } from './editor_menu';
-export { EditorMenu as EditorMenuComponent } from './editor_menu.component';
diff --git a/x-pack/plugins/canvas/public/components/workpad_header/element_menu/element_menu.component.tsx b/x-pack/plugins/canvas/public/components/workpad_header/element_menu/element_menu.component.tsx
index 1cfab236d9a9c9..8ac581b0866a46 100644
--- a/x-pack/plugins/canvas/public/components/workpad_header/element_menu/element_menu.component.tsx
+++ b/x-pack/plugins/canvas/public/components/workpad_header/element_menu/element_menu.component.tsx
@@ -12,11 +12,11 @@ import { EuiContextMenu, EuiIcon, EuiContextMenuPanelItemDescriptor } from '@ela
import { i18n } from '@kbn/i18n';
import { PrimaryActionPopover } from '../../../../../../../src/plugins/presentation_util/public';
import { getId } from '../../../lib/get_id';
+import { ClosePopoverFn } from '../../popover';
import { CONTEXT_MENU_TOP_BORDER_CLASSNAME } from '../../../../common/lib';
import { ElementSpec } from '../../../../types';
import { flattenPanelTree } from '../../../lib/flatten_panel_tree';
import { AssetManager } from '../../asset_manager';
-import { ClosePopoverFn } from '../../popover';
import { SavedElementsModal } from '../../saved_elements_modal';
interface CategorizedElementLists {
@@ -112,7 +112,7 @@ const categorizeElementsByType = (elements: ElementSpec[]): { [key: string]: Ele
return categories;
};
-export interface Props {
+interface Props {
/**
* Dictionary of elements from elements registry
*/
@@ -120,7 +120,7 @@ export interface Props {
/**
* Handler for adding a selected element to the workpad
*/
- addElement: (element: Partial) => void;
+ addElement: (element: ElementSpec) => void;
}
export const ElementMenu: FunctionComponent = ({ elements, addElement }) => {
diff --git a/x-pack/plugins/canvas/public/components/workpad_header/element_menu/index.ts b/x-pack/plugins/canvas/public/components/workpad_header/element_menu/index.ts
index 037bb84b0cdba4..52c8daece7690a 100644
--- a/x-pack/plugins/canvas/public/components/workpad_header/element_menu/index.ts
+++ b/x-pack/plugins/canvas/public/components/workpad_header/element_menu/index.ts
@@ -5,4 +5,5 @@
* 2.0.
*/
-export { ElementMenu } from './element_menu.component';
+export { ElementMenu } from './element_menu';
+export { ElementMenu as ElementMenuComponent } from './element_menu.component';
diff --git a/x-pack/plugins/canvas/public/components/workpad_header/workpad_header.component.tsx b/x-pack/plugins/canvas/public/components/workpad_header/workpad_header.component.tsx
index b84e4faf2925e7..f031d7c2631991 100644
--- a/x-pack/plugins/canvas/public/components/workpad_header/workpad_header.component.tsx
+++ b/x-pack/plugins/canvas/public/components/workpad_header/workpad_header.component.tsx
@@ -27,7 +27,6 @@ import { ElementMenu } from './element_menu';
import { ShareMenu } from './share_menu';
import { ViewMenu } from './view_menu';
import { LabsControl } from './labs_control';
-import { EditorMenu } from './editor_menu';
const strings = {
getFullScreenButtonAriaLabel: () =>
@@ -161,22 +160,24 @@ export const WorkpadHeader: FC = ({
- {isWriteable && (
-
-
- {{
- primaryActionButton: ,
- quickButtonGroup: ,
- addFromLibraryButton: ,
- extraButtons: [],
- }}
-
-
- )}
+ {isWriteable && (
+
+
+ {{
+ primaryActionButton: (
+
+ ),
+ quickButtonGroup: ,
+ addFromLibraryButton: ,
+ }}
+
+
+ )}
@@ -191,7 +192,6 @@ export const WorkpadHeader: FC = ({
-
diff --git a/x-pack/plugins/canvas/public/plugin.tsx b/x-pack/plugins/canvas/public/plugin.tsx
index 912055dd47a627..723d1afea2860f 100644
--- a/x-pack/plugins/canvas/public/plugin.tsx
+++ b/x-pack/plugins/canvas/public/plugin.tsx
@@ -8,7 +8,6 @@
import { BehaviorSubject } from 'rxjs';
import type { SharePluginSetup } from 'src/plugins/share/public';
import { ChartsPluginSetup, ChartsPluginStart } from 'src/plugins/charts/public';
-import { VisualizationsStart } from 'src/plugins/visualizations/public';
import { ReportingStart } from '../../reporting/public';
import {
CoreSetup,
@@ -64,7 +63,6 @@ export interface CanvasStartDeps {
charts: ChartsPluginStart;
data: DataPublicPluginStart;
presentationUtil: PresentationUtilPluginStart;
- visualizations: VisualizationsStart;
spaces?: SpacesPluginStart;
}
@@ -124,12 +122,7 @@ export class CanvasPlugin
const { pluginServices } = await import('./services');
pluginServices.setRegistry(
- pluginServiceRegistry.start({
- coreStart,
- startPlugins,
- appUpdater: this.appUpdater,
- initContext: this.initContext,
- })
+ pluginServiceRegistry.start({ coreStart, startPlugins, initContext: this.initContext })
);
// Load application bundle
diff --git a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad.ts b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad.ts
index bd9a4e7141c272..35e79b442a15d7 100644
--- a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad.ts
+++ b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad.ts
@@ -53,24 +53,14 @@ export const useWorkpad = (
workpad.aliasId = aliasId;
}
- if (storedWorkpad.id !== workpadId || storedWorkpad.aliasId !== aliasId) {
- dispatch(setAssets(assets));
- dispatch(setWorkpad(workpad, { loadPages }));
- dispatch(setZoomScale(1));
- }
+ dispatch(setAssets(assets));
+ dispatch(setWorkpad(workpad, { loadPages }));
+ dispatch(setZoomScale(1));
} catch (e) {
setError(e as Error | string);
}
})();
- }, [
- workpadId,
- dispatch,
- setError,
- loadPages,
- workpadResolve,
- storedWorkpad.id,
- storedWorkpad.aliasId,
- ]);
+ }, [workpadId, dispatch, setError, loadPages, workpadResolve]);
useEffect(() => {
(() => {
diff --git a/x-pack/plugins/canvas/public/services/embeddables.ts b/x-pack/plugins/canvas/public/services/embeddables.ts
index 26b150b7a53493..24d7a57e086f2d 100644
--- a/x-pack/plugins/canvas/public/services/embeddables.ts
+++ b/x-pack/plugins/canvas/public/services/embeddables.ts
@@ -5,12 +5,8 @@
* 2.0.
*/
-import {
- EmbeddableFactory,
- EmbeddableStateTransfer,
-} from '../../../../../src/plugins/embeddable/public';
+import { EmbeddableFactory } from '../../../../../src/plugins/embeddable/public';
export interface CanvasEmbeddablesService {
getEmbeddableFactories: () => IterableIterator;
- getStateTransfer: () => EmbeddableStateTransfer;
}
diff --git a/x-pack/plugins/canvas/public/services/index.ts b/x-pack/plugins/canvas/public/services/index.ts
index ed55f919e4c767..f4292810b80896 100644
--- a/x-pack/plugins/canvas/public/services/index.ts
+++ b/x-pack/plugins/canvas/public/services/index.ts
@@ -17,7 +17,6 @@ import { CanvasNavLinkService } from './nav_link';
import { CanvasNotifyService } from './notify';
import { CanvasPlatformService } from './platform';
import { CanvasReportingService } from './reporting';
-import { CanvasVisualizationsService } from './visualizations';
import { CanvasWorkpadService } from './workpad';
export interface CanvasPluginServices {
@@ -29,7 +28,6 @@ export interface CanvasPluginServices {
notify: CanvasNotifyService;
platform: CanvasPlatformService;
reporting: CanvasReportingService;
- visualizations: CanvasVisualizationsService;
workpad: CanvasWorkpadService;
}
@@ -46,6 +44,4 @@ export const useNavLinkService = () => (() => pluginServices.getHooks().navLink.
export const useNotifyService = () => (() => pluginServices.getHooks().notify.useService())();
export const usePlatformService = () => (() => pluginServices.getHooks().platform.useService())();
export const useReportingService = () => (() => pluginServices.getHooks().reporting.useService())();
-export const useVisualizationsService = () =>
- (() => pluginServices.getHooks().visualizations.useService())();
export const useWorkpadService = () => (() => pluginServices.getHooks().workpad.useService())();
diff --git a/x-pack/plugins/canvas/public/services/kibana/embeddables.ts b/x-pack/plugins/canvas/public/services/kibana/embeddables.ts
index 8d1a86edab3d89..054b9da7409fbb 100644
--- a/x-pack/plugins/canvas/public/services/kibana/embeddables.ts
+++ b/x-pack/plugins/canvas/public/services/kibana/embeddables.ts
@@ -16,5 +16,4 @@ export type EmbeddablesServiceFactory = KibanaPluginServiceFactory<
export const embeddablesServiceFactory: EmbeddablesServiceFactory = ({ startPlugins }) => ({
getEmbeddableFactories: startPlugins.embeddable.getEmbeddableFactories,
- getStateTransfer: startPlugins.embeddable.getStateTransfer,
});
diff --git a/x-pack/plugins/canvas/public/services/kibana/index.ts b/x-pack/plugins/canvas/public/services/kibana/index.ts
index 91767947bc0a65..1eb010e8d6f9da 100644
--- a/x-pack/plugins/canvas/public/services/kibana/index.ts
+++ b/x-pack/plugins/canvas/public/services/kibana/index.ts
@@ -22,7 +22,6 @@ import { navLinkServiceFactory } from './nav_link';
import { notifyServiceFactory } from './notify';
import { platformServiceFactory } from './platform';
import { reportingServiceFactory } from './reporting';
-import { visualizationsServiceFactory } from './visualizations';
import { workpadServiceFactory } from './workpad';
export { customElementServiceFactory } from './custom_element';
@@ -32,7 +31,6 @@ export { labsServiceFactory } from './labs';
export { notifyServiceFactory } from './notify';
export { platformServiceFactory } from './platform';
export { reportingServiceFactory } from './reporting';
-export { visualizationsServiceFactory } from './visualizations';
export { workpadServiceFactory } from './workpad';
export const pluginServiceProviders: PluginServiceProviders<
@@ -47,7 +45,6 @@ export const pluginServiceProviders: PluginServiceProviders<
notify: new PluginServiceProvider(notifyServiceFactory),
platform: new PluginServiceProvider(platformServiceFactory),
reporting: new PluginServiceProvider(reportingServiceFactory),
- visualizations: new PluginServiceProvider(visualizationsServiceFactory),
workpad: new PluginServiceProvider(workpadServiceFactory),
};
diff --git a/x-pack/plugins/canvas/public/services/kibana/visualizations.ts b/x-pack/plugins/canvas/public/services/kibana/visualizations.ts
deleted file mode 100644
index e319ec1c1f4272..00000000000000
--- a/x-pack/plugins/canvas/public/services/kibana/visualizations.ts
+++ /dev/null
@@ -1,21 +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; you may not use this file except in compliance with the Elastic License
- * 2.0.
- */
-
-import { KibanaPluginServiceFactory } from '../../../../../../src/plugins/presentation_util/public';
-import { CanvasStartDeps } from '../../plugin';
-import { CanvasVisualizationsService } from '../visualizations';
-
-export type VisualizationsServiceFactory = KibanaPluginServiceFactory<
- CanvasVisualizationsService,
- CanvasStartDeps
->;
-
-export const visualizationsServiceFactory: VisualizationsServiceFactory = ({ startPlugins }) => ({
- showNewVisModal: startPlugins.visualizations.showNewVisModal,
- getByGroup: startPlugins.visualizations.getByGroup,
- getAliases: startPlugins.visualizations.getAliases,
-});
diff --git a/x-pack/plugins/canvas/public/services/stubs/embeddables.ts b/x-pack/plugins/canvas/public/services/stubs/embeddables.ts
index 9c2cf4d0650abe..173d27563e2b2a 100644
--- a/x-pack/plugins/canvas/public/services/stubs/embeddables.ts
+++ b/x-pack/plugins/canvas/public/services/stubs/embeddables.ts
@@ -14,5 +14,4 @@ const noop = (..._args: any[]): any => {};
export const embeddablesServiceFactory: EmbeddablesServiceFactory = () => ({
getEmbeddableFactories: noop,
- getStateTransfer: noop,
});
diff --git a/x-pack/plugins/canvas/public/services/stubs/index.ts b/x-pack/plugins/canvas/public/services/stubs/index.ts
index 2216013a29c129..06a5ff49e9c04e 100644
--- a/x-pack/plugins/canvas/public/services/stubs/index.ts
+++ b/x-pack/plugins/canvas/public/services/stubs/index.ts
@@ -22,7 +22,6 @@ import { navLinkServiceFactory } from './nav_link';
import { notifyServiceFactory } from './notify';
import { platformServiceFactory } from './platform';
import { reportingServiceFactory } from './reporting';
-import { visualizationsServiceFactory } from './visualizations';
import { workpadServiceFactory } from './workpad';
export { customElementServiceFactory } from './custom_element';
@@ -32,7 +31,6 @@ export { navLinkServiceFactory } from './nav_link';
export { notifyServiceFactory } from './notify';
export { platformServiceFactory } from './platform';
export { reportingServiceFactory } from './reporting';
-export { visualizationsServiceFactory } from './visualizations';
export { workpadServiceFactory } from './workpad';
export const pluginServiceProviders: PluginServiceProviders = {
@@ -44,7 +42,6 @@ export const pluginServiceProviders: PluginServiceProviders;
-
-const noop = (..._args: any[]): any => {};
-
-export const visualizationsServiceFactory: VisualizationsServiceFactory = () => ({
- showNewVisModal: noop,
- getByGroup: noop,
- getAliases: noop,
-});
diff --git a/x-pack/plugins/canvas/public/services/visualizations.ts b/x-pack/plugins/canvas/public/services/visualizations.ts
deleted file mode 100644
index c602b1dd39f3d2..00000000000000
--- a/x-pack/plugins/canvas/public/services/visualizations.ts
+++ /dev/null
@@ -1,14 +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; you may not use this file except in compliance with the Elastic License
- * 2.0.
- */
-
-import { VisualizationsStart } from '../../../../../src/plugins/visualizations/public';
-
-export interface CanvasVisualizationsService {
- showNewVisModal: VisualizationsStart['showNewVisModal'];
- getByGroup: VisualizationsStart['getByGroup'];
- getAliases: VisualizationsStart['getAliases'];
-}
diff --git a/x-pack/plugins/canvas/public/state/reducers/embeddable.ts b/x-pack/plugins/canvas/public/state/reducers/embeddable.ts
index 092d4300d86b79..4cfdc7f21945f6 100644
--- a/x-pack/plugins/canvas/public/state/reducers/embeddable.ts
+++ b/x-pack/plugins/canvas/public/state/reducers/embeddable.ts
@@ -40,7 +40,7 @@ export const embeddableReducer = handleActions<
const element = pageWithElement.elements.find((elem) => elem.id === elementId);
- if (!element || element.expression === embeddableExpression) {
+ if (!element) {
return workpadState;
}
diff --git a/x-pack/plugins/canvas/server/plugin.ts b/x-pack/plugins/canvas/server/plugin.ts
index ebe43ba76a46ac..4071b891e4c3d7 100644
--- a/x-pack/plugins/canvas/server/plugin.ts
+++ b/x-pack/plugins/canvas/server/plugin.ts
@@ -14,7 +14,6 @@ import { ExpressionsServerSetup } from 'src/plugins/expressions/server';
import { BfetchServerSetup } from 'src/plugins/bfetch/server';
import { UsageCollectionSetup } from 'src/plugins/usage_collection/server';
import { HomeServerPluginSetup } from 'src/plugins/home/server';
-import { EmbeddableSetup } from 'src/plugins/embeddable/server';
import { ESSQL_SEARCH_STRATEGY } from '../common/lib/constants';
import { ReportingSetup } from '../../reporting/server';
import { PluginSetupContract as FeaturesPluginSetup } from '../../features/server';
@@ -31,7 +30,6 @@ import { CanvasRouteHandlerContext, createWorkpadRouteContext } from './workpad_
interface PluginsSetup {
expressions: ExpressionsServerSetup;
- embeddable: EmbeddableSetup;
features: FeaturesPluginSetup;
home: HomeServerPluginSetup;
bfetch: BfetchServerSetup;
@@ -84,12 +82,7 @@ export class CanvasPlugin implements Plugin {
const kibanaIndex = coreSetup.savedObjects.getKibanaIndex();
registerCanvasUsageCollector(plugins.usageCollection, kibanaIndex);
- setupInterpreter(expressionsFork, {
- embeddablePersistableStateService: {
- extract: plugins.embeddable.extract,
- inject: plugins.embeddable.inject,
- },
- });
+ setupInterpreter(expressionsFork);
coreSetup.getStartServices().then(([_, depsStart]) => {
const strategy = essqlSearchStrategyProvider();
diff --git a/x-pack/plugins/canvas/server/setup_interpreter.ts b/x-pack/plugins/canvas/server/setup_interpreter.ts
index 849ad79717056c..2fe23eb86c086f 100644
--- a/x-pack/plugins/canvas/server/setup_interpreter.ts
+++ b/x-pack/plugins/canvas/server/setup_interpreter.ts
@@ -7,15 +7,9 @@
import { ExpressionsServerSetup } from 'src/plugins/expressions/server';
import { functions } from '../canvas_plugin_src/functions/server';
-import {
- initFunctions as initExternalFunctions,
- InitializeArguments,
-} from '../canvas_plugin_src/functions/external';
+import { functions as externalFunctions } from '../canvas_plugin_src/functions/external';
-export function setupInterpreter(
- expressions: ExpressionsServerSetup,
- dependencies: InitializeArguments
-) {
+export function setupInterpreter(expressions: ExpressionsServerSetup) {
functions.forEach((f) => expressions.registerFunction(f));
- initExternalFunctions(dependencies).forEach((f) => expressions.registerFunction(f));
+ externalFunctions.forEach((f) => expressions.registerFunction(f));
}
diff --git a/x-pack/plugins/canvas/types/embeddables.ts b/x-pack/plugins/canvas/types/embeddables.ts
deleted file mode 100644
index b78efece59d8f8..00000000000000
--- a/x-pack/plugins/canvas/types/embeddables.ts
+++ /dev/null
@@ -1,16 +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; you may not use this file except in compliance with the Elastic License
- * 2.0.
- */
-
-import { TimeRange } from 'src/plugins/data/public';
-import { Filter } from '@kbn/es-query';
-import { EmbeddableInput as Input } from '../../../../src/plugins/embeddable/common/';
-
-export type EmbeddableInput = Input & {
- timeRange?: TimeRange;
- filters?: Filter[];
- savedObjectId?: string;
-};
diff --git a/x-pack/plugins/canvas/types/functions.ts b/x-pack/plugins/canvas/types/functions.ts
index c80102915ed953..2569e0b10685b7 100644
--- a/x-pack/plugins/canvas/types/functions.ts
+++ b/x-pack/plugins/canvas/types/functions.ts
@@ -10,8 +10,8 @@ import { UnwrapPromiseOrReturn } from '@kbn/utility-types';
import { functions as commonFunctions } from '../canvas_plugin_src/functions/common';
import { functions as browserFunctions } from '../canvas_plugin_src/functions/browser';
import { functions as serverFunctions } from '../canvas_plugin_src/functions/server';
-import { initFunctions as initExternalFunctions } from '../canvas_plugin_src/functions/external';
-import { initFunctions as initClientFunctions } from '../public/functions';
+import { functions as externalFunctions } from '../canvas_plugin_src/functions/external';
+import { initFunctions } from '../public/functions';
/**
* A `ExpressionFunctionFactory` is a powerful type used for any function that produces
@@ -90,11 +90,9 @@ export type FunctionFactory =
type CommonFunction = FunctionFactory;
type BrowserFunction = FunctionFactory;
type ServerFunction = FunctionFactory;
-type ExternalFunction = FunctionFactory<
- ReturnType extends Array ? U : never
->;
+type ExternalFunction = FunctionFactory;
type ClientFunctions = FunctionFactory<
- ReturnType extends Array ? U : never
+ ReturnType extends Array ? U : never
>;
/**
diff --git a/x-pack/plugins/canvas/types/index.ts b/x-pack/plugins/canvas/types/index.ts
index 930f3372920884..09ae1510be6da0 100644
--- a/x-pack/plugins/canvas/types/index.ts
+++ b/x-pack/plugins/canvas/types/index.ts
@@ -9,7 +9,6 @@ export * from '../../../../src/plugins/expressions/common';
export * from './assets';
export * from './canvas';
export * from './elements';
-export * from './embeddables';
export * from './filters';
export * from './functions';
export * from './renderers';
diff --git a/x-pack/plugins/cases/public/components/configure_cases/index.test.tsx b/x-pack/plugins/cases/public/components/configure_cases/index.test.tsx
index 1fed1d90689be8..990d44584cf055 100644
--- a/x-pack/plugins/cases/public/components/configure_cases/index.test.tsx
+++ b/x-pack/plugins/cases/public/components/configure_cases/index.test.tsx
@@ -47,6 +47,7 @@ describe('ConfigureCases', () => {
iconClass: 'logoSecurity',
});
});
+
beforeEach(() => {
useActionTypesMock.mockImplementation(() => useActionTypesResponse);
});
@@ -451,150 +452,149 @@ describe('ConfigureCases', () => {
).toBe('Update My Connector 2');
});
});
-});
-// Failing: See https://github.com/elastic/kibana/issues/115366
-describe.skip('closure options', () => {
- let wrapper: ReactWrapper;
- let persistCaseConfigure: jest.Mock;
+ describe('closure options', () => {
+ let wrapper: ReactWrapper;
+ let persistCaseConfigure: jest.Mock;
- beforeEach(() => {
- persistCaseConfigure = jest.fn();
- useCaseConfigureMock.mockImplementation(() => ({
- ...useCaseConfigureResponse,
- mapping: null,
- closureType: 'close-by-user',
- connector: {
- id: 'servicenow-1',
- name: 'My connector',
- type: ConnectorTypes.serviceNowITSM,
- fields: null,
- },
- currentConfiguration: {
+ beforeEach(() => {
+ persistCaseConfigure = jest.fn();
+ useCaseConfigureMock.mockImplementation(() => ({
+ ...useCaseConfigureResponse,
+ mapping: null,
+ closureType: 'close-by-user',
connector: {
- id: 'My connector',
+ id: 'servicenow-1',
name: 'My connector',
- type: ConnectorTypes.jira,
+ type: ConnectorTypes.serviceNowITSM,
fields: null,
},
- closureType: 'close-by-user',
- },
- persistCaseConfigure,
- }));
- useConnectorsMock.mockImplementation(() => useConnectorsResponse);
- useGetUrlSearchMock.mockImplementation(() => searchURL);
+ currentConfiguration: {
+ connector: {
+ id: 'My connector',
+ name: 'My connector',
+ type: ConnectorTypes.jira,
+ fields: null,
+ },
+ closureType: 'close-by-user',
+ },
+ persistCaseConfigure,
+ }));
+ useConnectorsMock.mockImplementation(() => useConnectorsResponse);
+ useGetUrlSearchMock.mockImplementation(() => searchURL);
- wrapper = mount(, {
- wrappingComponent: TestProviders,
+ wrapper = mount(, {
+ wrappingComponent: TestProviders,
+ });
});
- });
- test('it submits the configuration correctly when changing closure type', () => {
- wrapper.find('input[id="close-by-pushing"]').simulate('change');
- wrapper.update();
+ test('it submits the configuration correctly when changing closure type', () => {
+ wrapper.find('input[id="close-by-pushing"]').simulate('change');
+ wrapper.update();
- expect(persistCaseConfigure).toHaveBeenCalled();
- expect(persistCaseConfigure).toHaveBeenCalledWith({
- connector: {
- id: 'servicenow-1',
- name: 'My connector',
- type: ConnectorTypes.serviceNowITSM,
- fields: null,
- },
- closureType: 'close-by-pushing',
+ expect(persistCaseConfigure).toHaveBeenCalled();
+ expect(persistCaseConfigure).toHaveBeenCalledWith({
+ connector: {
+ id: 'servicenow-1',
+ name: 'My connector',
+ type: ConnectorTypes.serviceNowITSM,
+ fields: null,
+ },
+ closureType: 'close-by-pushing',
+ });
});
});
-});
-describe('user interactions', () => {
- beforeEach(() => {
- useCaseConfigureMock.mockImplementation(() => ({
- ...useCaseConfigureResponse,
- mapping: null,
- closureType: 'close-by-user',
- connector: {
- id: 'resilient-2',
- name: 'unchanged',
- type: ConnectorTypes.resilient,
- fields: null,
- },
- currentConfiguration: {
+ describe('user interactions', () => {
+ beforeEach(() => {
+ useCaseConfigureMock.mockImplementation(() => ({
+ ...useCaseConfigureResponse,
+ mapping: null,
+ closureType: 'close-by-user',
connector: {
id: 'resilient-2',
name: 'unchanged',
- type: ConnectorTypes.serviceNowITSM,
+ type: ConnectorTypes.resilient,
fields: null,
},
- closureType: 'close-by-user',
- },
- }));
- useConnectorsMock.mockImplementation(() => useConnectorsResponse);
- useGetUrlSearchMock.mockImplementation(() => searchURL);
- });
-
- test('it show the add flyout when pressing the add connector button', async () => {
- const wrapper = mount(, {
- wrappingComponent: TestProviders,
+ currentConfiguration: {
+ connector: {
+ id: 'resilient-2',
+ name: 'unchanged',
+ type: ConnectorTypes.serviceNowITSM,
+ fields: null,
+ },
+ closureType: 'close-by-user',
+ },
+ }));
+ useConnectorsMock.mockImplementation(() => useConnectorsResponse);
+ useGetUrlSearchMock.mockImplementation(() => searchURL);
});
- wrapper.find('button[data-test-subj="dropdown-connectors"]').simulate('click');
- wrapper.find('button[data-test-subj="dropdown-connector-add-connector"]').simulate('click');
+ test('it show the add flyout when pressing the add connector button', async () => {
+ const wrapper = mount(, {
+ wrappingComponent: TestProviders,
+ });
- await waitFor(() => {
- wrapper.update();
- expect(wrapper.find('ConnectorAddFlyout').exists()).toBe(true);
- expect(wrapper.find('ConnectorAddFlyout').prop('actionTypes')).toEqual([
- expect.objectContaining({
- id: '.servicenow',
- }),
- expect.objectContaining({
- id: '.jira',
- }),
- expect.objectContaining({
- id: '.resilient',
- }),
- expect.objectContaining({
- id: '.servicenow-sir',
- }),
- ]);
+ wrapper.find('button[data-test-subj="dropdown-connectors"]').simulate('click');
+ wrapper.find('button[data-test-subj="dropdown-connector-add-connector"]').simulate('click');
+
+ await waitFor(() => {
+ wrapper.update();
+ expect(wrapper.find('ConnectorAddFlyout').exists()).toBe(true);
+ expect(wrapper.find('ConnectorAddFlyout').prop('actionTypes')).toEqual([
+ expect.objectContaining({
+ id: '.servicenow',
+ }),
+ expect.objectContaining({
+ id: '.jira',
+ }),
+ expect.objectContaining({
+ id: '.resilient',
+ }),
+ expect.objectContaining({
+ id: '.servicenow-sir',
+ }),
+ ]);
+ });
});
- });
- test('it show the edit flyout when pressing the update connector button', async () => {
- const actionType = actionTypeRegistryMock.createMockActionTypeModel({
- id: '.resilient',
- validateConnector: () => {
- return Promise.resolve({});
- },
- validateParams: () => {
- const validationResult = { errors: {} };
- return Promise.resolve(validationResult);
- },
- actionConnectorFields: null,
- });
-
- useKibanaMock().services.triggersActionsUi.actionTypeRegistry.get = jest
- .fn()
- .mockReturnValue(actionType);
- useKibanaMock().services.triggersActionsUi.actionTypeRegistry.has = jest
- .fn()
- .mockReturnValue(true);
-
- const wrapper = mount(, {
- wrappingComponent: TestProviders,
- });
- wrapper
- .find('button[data-test-subj="case-configure-update-selected-connector-button"]')
- .simulate('click');
-
- await waitFor(() => {
- wrapper.update();
- expect(wrapper.find('ConnectorEditFlyout').exists()).toBe(true);
- expect(wrapper.find('ConnectorEditFlyout').prop('initialConnector')).toEqual(connectors[1]);
- });
+ test('it show the edit flyout when pressing the update connector button', async () => {
+ const actionType = actionTypeRegistryMock.createMockActionTypeModel({
+ id: '.resilient',
+ validateConnector: () => {
+ return Promise.resolve({});
+ },
+ validateParams: () => {
+ const validationResult = { errors: {} };
+ return Promise.resolve(validationResult);
+ },
+ actionConnectorFields: null,
+ });
+
+ useKibanaMock().services.triggersActionsUi.actionTypeRegistry.get = jest
+ .fn()
+ .mockReturnValue(actionType);
+ useKibanaMock().services.triggersActionsUi.actionTypeRegistry.has = jest
+ .fn()
+ .mockReturnValue(true);
+
+ const wrapper = mount(, {
+ wrappingComponent: TestProviders,
+ });
+ wrapper
+ .find('button[data-test-subj="case-configure-update-selected-connector-button"]')
+ .simulate('click');
+
+ await waitFor(() => {
+ wrapper.update();
+ expect(wrapper.find('ConnectorEditFlyout').exists()).toBe(true);
+ expect(wrapper.find('ConnectorEditFlyout').prop('initialConnector')).toEqual(connectors[1]);
+ });
- expect(
- wrapper.find('[data-test-subj="case-configure-action-bottom-bar"]').exists()
- ).toBeFalsy();
+ expect(
+ wrapper.find('[data-test-subj="case-configure-action-bottom-bar"]').exists()
+ ).toBeFalsy();
+ });
});
});
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curations_router.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curations_router.test.tsx
index c0278c765e85ee..9598212d3e0c98 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curations_router.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curations_router.test.tsx
@@ -5,9 +5,6 @@
* 2.0.
*/
-import '../../../__mocks__/shallow_useeffect.mock';
-import '../../../__mocks__/react_router';
-import { setMockActions, setMockValues } from '../../../__mocks__/kea_logic';
import '../../__mocks__/engine_logic.mock';
import React from 'react';
@@ -15,110 +12,13 @@ import { Route, Switch } from 'react-router-dom';
import { shallow } from 'enzyme';
-import { LogRetentionOptions } from '../log_retention';
-
import { CurationsRouter } from './';
-const MOCK_VALUES = {
- // CurationsSettingsLogic
- dataLoading: false,
- curationsSettings: {
- enabled: true,
- mode: 'automatic',
- },
- // LogRetentionLogic
- logRetention: {
- [LogRetentionOptions.Analytics]: {
- enabled: true,
- },
- },
- // LicensingLogic
- hasPlatinumLicense: true,
-};
-
-const MOCK_ACTIONS = {
- // CurationsSettingsLogic
- loadCurationsSettings: jest.fn(),
- onSkipLoadingCurationsSettings: jest.fn(),
- // LogRetentionLogic
- fetchLogRetention: jest.fn(),
-};
-
describe('CurationsRouter', () => {
- beforeEach(() => {
- jest.clearAllMocks();
- setMockActions(MOCK_ACTIONS);
- });
-
it('renders', () => {
const wrapper = shallow();
expect(wrapper.find(Switch)).toHaveLength(1);
expect(wrapper.find(Route)).toHaveLength(4);
});
-
- it('loads log retention settings', () => {
- setMockValues(MOCK_VALUES);
- shallow();
-
- expect(MOCK_ACTIONS.fetchLogRetention).toHaveBeenCalled();
- });
-
- describe('when the user has no platinum license', () => {
- beforeEach(() => {
- setMockValues({
- ...MOCK_VALUES,
- hasPlatinumLicense: false,
- });
- });
-
- it('it does not fetch log retention', () => {
- shallow();
- expect(MOCK_ACTIONS.fetchLogRetention).toHaveBeenCalledTimes(0);
- });
- });
-
- describe('loading curation settings based on log retention', () => {
- it('loads curation settings when log retention is enabled', () => {
- setMockValues({
- ...MOCK_VALUES,
- logRetention: {
- [LogRetentionOptions.Analytics]: {
- enabled: true,
- },
- },
- });
-
- shallow();
-
- expect(MOCK_ACTIONS.loadCurationsSettings).toHaveBeenCalledTimes(1);
- });
-
- it('skips loading curation settings when log retention is disabled', () => {
- setMockValues({
- ...MOCK_VALUES,
- logRetention: {
- [LogRetentionOptions.Analytics]: {
- enabled: false,
- },
- },
- });
-
- shallow();
-
- expect(MOCK_ACTIONS.onSkipLoadingCurationsSettings).toHaveBeenCalledTimes(1);
- });
-
- it('takes no action if log retention has not yet been loaded', () => {
- setMockValues({
- ...MOCK_VALUES,
- logRetention: null,
- });
-
- shallow();
-
- expect(MOCK_ACTIONS.loadCurationsSettings).toHaveBeenCalledTimes(0);
- expect(MOCK_ACTIONS.onSkipLoadingCurationsSettings).toHaveBeenCalledTimes(0);
- });
- });
});
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curations_router.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curations_router.tsx
index a3b000ea5054ac..693e5406b714b3 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curations_router.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curations_router.tsx
@@ -5,53 +5,20 @@
* 2.0.
*/
-import React, { useEffect } from 'react';
+import React from 'react';
import { Route, Switch } from 'react-router-dom';
-import { useValues, useActions } from 'kea';
-
-import { LicensingLogic } from '../../../shared/licensing';
import {
ENGINE_CURATIONS_PATH,
ENGINE_CURATIONS_NEW_PATH,
ENGINE_CURATION_PATH,
ENGINE_CURATION_SUGGESTION_PATH,
} from '../../routes';
-import { LogRetentionLogic, LogRetentionOptions } from '../log_retention';
import { Curation } from './curation';
import { Curations, CurationCreation, CurationSuggestion } from './views';
-import { CurationsSettingsLogic } from './views/curations_settings';
export const CurationsRouter: React.FC = () => {
- // We need to loadCurationsSettings here so they are available across all views
-
- const { hasPlatinumLicense } = useValues(LicensingLogic);
-
- const { loadCurationsSettings, onSkipLoadingCurationsSettings } =
- useActions(CurationsSettingsLogic);
-
- const { logRetention } = useValues(LogRetentionLogic);
- const { fetchLogRetention } = useActions(LogRetentionLogic);
-
- const analyticsDisabled = !logRetention?.[LogRetentionOptions.Analytics].enabled;
-
- useEffect(() => {
- if (hasPlatinumLicense) {
- fetchLogRetention();
- }
- }, [hasPlatinumLicense]);
-
- useEffect(() => {
- if (logRetention) {
- if (!analyticsDisabled) {
- loadCurationsSettings();
- } else {
- onSkipLoadingCurationsSettings();
- }
- }
- }, [logRetention]);
-
return (
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations.tsx
index 2207555772b5bf..b0f4f03789af22 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations.tsx
@@ -24,17 +24,15 @@ import { getCurationsBreadcrumbs } from '../utils';
import { CurationsHistory } from './curations_history/curations_history';
import { CurationsOverview } from './curations_overview';
-import { CurationsSettings, CurationsSettingsLogic } from './curations_settings';
+import { CurationsSettings } from './curations_settings';
export const Curations: React.FC = () => {
- const { dataLoading: curationsDataLoading, meta, selectedPageTab } = useValues(CurationsLogic);
+ const { dataLoading, meta, selectedPageTab } = useValues(CurationsLogic);
const { loadCurations, onSelectPageTab } = useActions(CurationsLogic);
const {
engine: { search_relevance_suggestions_active: searchRelevanceSuggestionsActive },
} = useValues(EngineLogic);
- const { dataLoading: curationsSettingsDataLoading } = useValues(CurationsSettingsLogic);
-
const suggestionsEnabled = searchRelevanceSuggestionsActive;
const OVERVIEW_TAB = {
@@ -82,8 +80,6 @@ export const Curations: React.FC = () => {
loadCurations();
}, [meta.page.current]);
- const isLoading = curationsSettingsDataLoading || curationsDataLoading;
-
return (
{
{CREATE_NEW_CURATION_TITLE}
,
],
- tabs: isLoading ? undefined : pageTabs,
+ tabs: dataLoading ? undefined : pageTabs,
}}
- isLoading={isLoading}
+ isLoading={dataLoading}
>
{selectedPageTab === 'overview' && }
{selectedPageTab === 'history' && }
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_settings/curations_settings.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_settings/curations_settings.test.tsx
index 3b01d1e41c2718..4b4e11c31d4b88 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_settings/curations_settings.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_settings/curations_settings.test.tsx
@@ -17,6 +17,8 @@ import { shallow, ShallowWrapper } from 'enzyme';
import { EuiButtonEmpty, EuiCallOut, EuiSwitch } from '@elastic/eui';
+import { mountWithIntl } from '@kbn/test/jest';
+
import { Loading } from '../../../../../shared/loading';
import { EuiButtonTo } from '../../../../../shared/react_router_helpers';
import { DataPanel } from '../../../data_panel';
@@ -44,6 +46,8 @@ const MOCK_VALUES = {
const MOCK_ACTIONS = {
// CurationsSettingsLogic
+ loadCurationsSettings: jest.fn(),
+ onSkipLoadingCurationsSettings: jest.fn(),
toggleCurationsEnabled: jest.fn(),
toggleCurationsMode: jest.fn(),
// LogRetentionLogic
@@ -56,6 +60,14 @@ describe('CurationsSettings', () => {
setMockActions(MOCK_ACTIONS);
});
+ it('loads curations and log retention settings on load', () => {
+ setMockValues(MOCK_VALUES);
+ mountWithIntl();
+
+ expect(MOCK_ACTIONS.loadCurationsSettings).toHaveBeenCalled();
+ expect(MOCK_ACTIONS.fetchLogRetention).toHaveBeenCalled();
+ });
+
it('contains a switch to toggle curations settings', () => {
let wrapper: ShallowWrapper;
@@ -154,6 +166,50 @@ describe('CurationsSettings', () => {
expect(wrapper.is(Loading)).toBe(true);
});
+ describe('loading curation settings based on log retention', () => {
+ it('loads curation settings when log retention is enabled', () => {
+ setMockValues({
+ ...MOCK_VALUES,
+ logRetention: {
+ [LogRetentionOptions.Analytics]: {
+ enabled: true,
+ },
+ },
+ });
+
+ shallow();
+
+ expect(MOCK_ACTIONS.loadCurationsSettings).toHaveBeenCalledTimes(1);
+ });
+
+ it('skips loading curation settings when log retention is enabled', () => {
+ setMockValues({
+ ...MOCK_VALUES,
+ logRetention: {
+ [LogRetentionOptions.Analytics]: {
+ enabled: false,
+ },
+ },
+ });
+
+ shallow();
+
+ expect(MOCK_ACTIONS.onSkipLoadingCurationsSettings).toHaveBeenCalledTimes(1);
+ });
+
+ it('takes no action if log retention has not yet been loaded', () => {
+ setMockValues({
+ ...MOCK_VALUES,
+ logRetention: null,
+ });
+
+ shallow();
+
+ expect(MOCK_ACTIONS.loadCurationsSettings).toHaveBeenCalledTimes(0);
+ expect(MOCK_ACTIONS.onSkipLoadingCurationsSettings).toHaveBeenCalledTimes(0);
+ });
+ });
+
describe('when the user has no platinum license', () => {
beforeEach(() => {
setMockValues({
@@ -162,6 +218,11 @@ describe('CurationsSettings', () => {
});
});
+ it('it does not fetch log retention', () => {
+ shallow();
+ expect(MOCK_ACTIONS.fetchLogRetention).toHaveBeenCalledTimes(0);
+ });
+
it('shows a CTA to upgrade your license when the user when the user', () => {
const wrapper = shallow();
expect(wrapper.is(DataPanel)).toBe(true);
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_settings/curations_settings.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_settings/curations_settings.tsx
index a5d4a33d8b870b..de669298b11d95 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_settings/curations_settings.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_settings/curations_settings.tsx
@@ -5,7 +5,7 @@
* 2.0.
*/
-import React from 'react';
+import React, { useEffect } from 'react';
import { useActions, useValues } from 'kea';
@@ -43,12 +43,34 @@ export const CurationsSettings: React.FC = () => {
curationsSettings: { enabled, mode },
dataLoading,
} = useValues(CurationsSettingsLogic);
- const { toggleCurationsEnabled, toggleCurationsMode } = useActions(CurationsSettingsLogic);
+ const {
+ loadCurationsSettings,
+ onSkipLoadingCurationsSettings,
+ toggleCurationsEnabled,
+ toggleCurationsMode,
+ } = useActions(CurationsSettingsLogic);
const { isLogRetentionUpdating, logRetention } = useValues(LogRetentionLogic);
+ const { fetchLogRetention } = useActions(LogRetentionLogic);
const analyticsDisabled = !logRetention?.[LogRetentionOptions.Analytics].enabled;
+ useEffect(() => {
+ if (hasPlatinumLicense) {
+ fetchLogRetention();
+ }
+ }, [hasPlatinumLicense]);
+
+ useEffect(() => {
+ if (logRetention) {
+ if (!analyticsDisabled) {
+ loadCurationsSettings();
+ } else {
+ onSkipLoadingCurationsSettings();
+ }
+ }
+ }, [logRetention]);
+
if (!hasPlatinumLicense)
return (
{
@@ -49,12 +49,12 @@ describe('PrecisionSlider', () => {
expect(wrapper.find('[data-test-subj="PrecisionRange"]').prop('value')).toEqual(2);
});
- it('calls updatePrecision on change', () => {
+ it('updates the precision on change', () => {
wrapper
.find('[data-test-subj="PrecisionRange"]')
.simulate('change', { target: { value: 10 } });
- expect(MOCK_ACTIONS.updatePrecision).toHaveBeenCalledWith(10);
+ expect(MOCK_ACTIONS.setPrecision).toHaveBeenCalledWith(10);
});
});
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/components/precision_slider/precision_slider.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/components/precision_slider/precision_slider.tsx
index 6fcfb28cb9e376..8e7a59c290ce2e 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/components/precision_slider/precision_slider.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/components/precision_slider/precision_slider.tsx
@@ -33,7 +33,7 @@ export const PrecisionSlider: React.FC = () => {
searchSettings: { precision },
} = useValues(RelevanceTuningLogic);
- const { updatePrecision } = useActions(RelevanceTuningLogic);
+ const { setPrecision } = useActions(RelevanceTuningLogic);
const stepDescription = STEP_DESCRIPTIONS[precision];
@@ -102,7 +102,7 @@ export const PrecisionSlider: React.FC = () => {
data-test-subj="PrecisionRange"
value={precision}
onChange={(e) => {
- updatePrecision(parseInt((e.target as HTMLInputElement).value, 10));
+ setPrecision(parseInt((e.target as HTMLInputElement).value, 10));
}}
min={1}
max={11}
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_logic.test.ts
index 7590633b7afef4..193c5dbe8ac24d 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_logic.test.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_logic.test.ts
@@ -228,10 +228,10 @@ describe('RelevanceTuningLogic', () => {
});
});
- describe('updatePrecision', () => {
+ describe('setPrecision', () => {
it('should set precision inside search settings and set unsavedChanges to true', () => {
mount();
- RelevanceTuningLogic.actions.updatePrecision(9);
+ RelevanceTuningLogic.actions.setPrecision(9);
expect(RelevanceTuningLogic.values).toEqual({
...DEFAULT_VALUES,
@@ -1007,15 +1007,24 @@ describe('RelevanceTuningLogic', () => {
});
});
- describe('updateSearchValue', () => {
- it('should update the query then update search results', () => {
+ describe('setSearchQuery', () => {
+ it('shoulds update search results', () => {
+ mount();
+ jest.spyOn(RelevanceTuningLogic.actions, 'getSearchResults');
+
+ RelevanceTuningLogic.actions.setSearchQuery('foo');
+
+ expect(RelevanceTuningLogic.actions.getSearchResults).toHaveBeenCalled();
+ });
+ });
+
+ describe('setPrecision', () => {
+ it('shoulds update search results', () => {
mount();
- jest.spyOn(RelevanceTuningLogic.actions, 'setSearchQuery');
jest.spyOn(RelevanceTuningLogic.actions, 'getSearchResults');
- RelevanceTuningLogic.actions.updateSearchValue('foo');
+ RelevanceTuningLogic.actions.setPrecision(9);
- expect(RelevanceTuningLogic.actions.setSearchQuery).toHaveBeenCalledWith('foo');
expect(RelevanceTuningLogic.actions.getSearchResults).toHaveBeenCalled();
});
});
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_logic.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_logic.ts
index 02df792f515a29..c94de74b5ab22e 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_logic.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_logic.ts
@@ -88,8 +88,7 @@ interface RelevanceTuningActions {
optionType: keyof Pick;
value: string;
};
- updatePrecision(precision: number): { precision: number };
- updateSearchValue(query: string): string;
+ setPrecision(precision: number): { precision: number };
}
interface RelevanceTuningValues {
@@ -144,8 +143,7 @@ export const RelevanceTuningLogic = kea<
optionType,
value,
}),
- updatePrecision: (precision) => ({ precision }),
- updateSearchValue: (query) => query,
+ setPrecision: (precision) => ({ precision }),
}),
reducers: () => ({
searchSettings: [
@@ -158,7 +156,7 @@ export const RelevanceTuningLogic = kea<
onInitializeRelevanceTuning: (_, { searchSettings }) => searchSettings,
setSearchSettings: (_, { searchSettings }) => searchSettings,
setSearchSettingsResponse: (_, { searchSettings }) => searchSettings,
- updatePrecision: (currentSearchSettings, { precision }) => ({
+ setPrecision: (currentSearchSettings, { precision }) => ({
...currentSearchSettings,
precision,
}),
@@ -191,7 +189,7 @@ export const RelevanceTuningLogic = kea<
unsavedChanges: [
false,
{
- updatePrecision: () => true,
+ setPrecision: () => true,
setSearchSettings: () => true,
setSearchSettingsResponse: () => false,
},
@@ -268,7 +266,11 @@ export const RelevanceTuningLogic = kea<
const { engineName } = EngineLogic.values;
const { http } = HttpLogic.values;
- const { search_fields: searchFields, boosts } = removeBoostStateProps(values.searchSettings);
+ const {
+ search_fields: searchFields,
+ boosts,
+ precision,
+ } = removeBoostStateProps(values.searchSettings);
const url = `/internal/app_search/engines/${engineName}/search`;
actions.setResultsLoading(true);
@@ -283,6 +285,7 @@ export const RelevanceTuningLogic = kea<
body: JSON.stringify({
boosts: isEmpty(filteredBoosts) ? undefined : filteredBoosts,
search_fields: isEmpty(searchFields) ? undefined : searchFields,
+ precision,
}),
});
@@ -472,8 +475,10 @@ export const RelevanceTuningLogic = kea<
},
});
},
- updateSearchValue: (query) => {
- actions.setSearchQuery(query);
+ setSearchQuery: () => {
+ actions.getSearchResults();
+ },
+ setPrecision: () => {
actions.getSearchResults();
},
}),
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_preview.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_preview.test.tsx
index b39faa60294367..32325c13efdaea 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_preview.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_preview.test.tsx
@@ -22,7 +22,7 @@ describe('RelevanceTuningPreview', () => {
const result3 = { id: { raw: 3 } };
const actions = {
- updateSearchValue: jest.fn(),
+ setSearchQuery: jest.fn(),
};
const values = {
@@ -79,7 +79,7 @@ describe('RelevanceTuningPreview', () => {
wrapper.find(EuiFieldSearch).simulate('change', { target: { value: 'some search text' } });
- expect(actions.updateSearchValue).toHaveBeenCalledWith('some search text');
+ expect(actions.setSearchQuery).toHaveBeenCalledWith('some search text');
});
it('will show user a prompt to enter a query if they have not entered one', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_preview.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_preview.tsx
index 4f3b20b419e802..3a36a3df2b4722 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_preview.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_preview.tsx
@@ -44,7 +44,7 @@ const noResultsCallout = (
);
export const RelevanceTuningPreview: React.FC = () => {
- const { updateSearchValue } = useActions(RelevanceTuningLogic);
+ const { setSearchQuery } = useActions(RelevanceTuningLogic);
const { searchResults, schema } = useValues(RelevanceTuningLogic);
const { engineName, isMetaEngine } = useValues(EngineLogic);
@@ -59,7 +59,7 @@ export const RelevanceTuningPreview: React.FC = () => {
updateSearchValue(e.target.value)}
+ onChange={(e) => setSearchQuery(e.target.value)}
placeholder={i18n.translate(
'xpack.enterpriseSearch.appSearch.engine.relevanceTuning.preview.searchPlaceholder',
{
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/utils.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/utils.ts
index be953f973ebf83..0edace74d0cb95 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/utils.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/utils.ts
@@ -16,7 +16,7 @@ export const filterIfTerm = (array: string[], filterTerm: string): string[] => {
return filterTerm === '' ? array : array.filter((item) => item.includes(filterTerm));
};
-export const removeBoostStateProps = (searchSettings: SearchSettings) => {
+export const removeBoostStateProps = (searchSettings: SearchSettings): SearchSettings => {
const updatedSettings = cloneDeep(searchSettings);
const { boosts } = updatedSettings;
const keys = Object.keys(boosts);
diff --git a/x-pack/plugins/file_upload/kibana.json b/x-pack/plugins/file_upload/kibana.json
index e69c5e34bc09bf..f70bc6377972a1 100644
--- a/x-pack/plugins/file_upload/kibana.json
+++ b/x-pack/plugins/file_upload/kibana.json
@@ -1,6 +1,6 @@
{
"id": "fileUpload",
- "version": "8.0.0",
+ "version": "8.1.0",
"kibanaVersion": "kibana",
"server": true,
"ui": true,
diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/integration_preference.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/integration_preference.tsx
index 9c9027fb94ac52..fa9b9a7ed190e0 100644
--- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/integration_preference.tsx
+++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/integration_preference.tsx
@@ -22,6 +22,8 @@ import {
EuiFlexItem,
} from '@elastic/eui';
+import { useStartServices } from '../../../hooks';
+
export type IntegrationPreferenceType = 'recommended' | 'beats' | 'agent';
interface Option {
@@ -34,23 +36,6 @@ export interface Props {
onChange: (type: IntegrationPreferenceType) => void;
}
-const link = (
-
-
-
-);
-
-const title = (
-
-);
-
const recommendedTooltip = (
{
const [idSelected, setIdSelected] = React.useState(initialType);
+
+ const { docLinks } = useStartServices();
+
+ const link = (
+
+
+
+ );
+
+ const title = (
+
+ );
+
const radios = options.map((option) => ({
id: option.type,
value: option.type,
diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.tsx
index 6e3eba19c52e3d..c8c6f493568109 100644
--- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.tsx
+++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.tsx
@@ -271,6 +271,7 @@ export function Detail() {
{
path: pagePathGetters.integration_details_policies({
pkgkey,
+ ...(integration ? { integration } : {}),
})[1],
},
];
@@ -289,6 +290,7 @@ export function Detail() {
{
path: pagePathGetters.integration_details_overview({
pkgkey,
+ ...(integration ? { integration } : {}),
})[1],
},
],
diff --git a/x-pack/plugins/fleet/server/services/agents/helpers.ts b/x-pack/plugins/fleet/server/services/agents/helpers.ts
index 609d5ba6c83a05..a4a7803d35e2cb 100644
--- a/x-pack/plugins/fleet/server/services/agents/helpers.ts
+++ b/x-pack/plugins/fleet/server/services/agents/helpers.ts
@@ -42,5 +42,9 @@ export function agentSOAttributesToFleetServerAgentDoc(
doc.policy_revision_idx = policyRevison;
}
+ if (!doc.updated_at) {
+ doc.updated_at = new Date().toISOString();
+ }
+
return doc;
}
diff --git a/x-pack/plugins/global_search_bar/kibana.json b/x-pack/plugins/global_search_bar/kibana.json
index 5c0a9999b8e3a5..94b8aba2dd7f9f 100644
--- a/x-pack/plugins/global_search_bar/kibana.json
+++ b/x-pack/plugins/global_search_bar/kibana.json
@@ -4,7 +4,7 @@
"name": "Kibana Core",
"githubTeam": "kibana-core"
},
- "version": "8.0.0",
+ "version": "8.1.0",
"kibanaVersion": "kibana",
"server": false,
"ui": true,
diff --git a/x-pack/plugins/graph/kibana.json b/x-pack/plugins/graph/kibana.json
index 410a5e2c160d6f..03729c706df25d 100644
--- a/x-pack/plugins/graph/kibana.json
+++ b/x-pack/plugins/graph/kibana.json
@@ -1,6 +1,6 @@
{
"id": "graph",
- "version": "8.0.0",
+ "version": "8.1.0",
"kibanaVersion": "kibana",
"server": true,
"ui": true,
@@ -29,4 +29,4 @@
"name": "Data Discovery",
"githubTeam": "kibana-data-discovery"
}
-}
\ No newline at end of file
+}
diff --git a/x-pack/plugins/grokdebugger/kibana.json b/x-pack/plugins/grokdebugger/kibana.json
index 692aa16329d549..f8cb75f7d10b66 100644
--- a/x-pack/plugins/grokdebugger/kibana.json
+++ b/x-pack/plugins/grokdebugger/kibana.json
@@ -1,6 +1,6 @@
{
"id": "grokdebugger",
- "version": "8.0.0",
+ "version": "8.1.0",
"kibanaVersion": "kibana",
"owner": {
"name": "Stack Management",
diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/timing.test.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/timing.test.ts
index be4f99103b319e..4c553cac02303b 100644
--- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/timing.test.ts
+++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/timing.test.ts
@@ -12,7 +12,8 @@ import { PhaseWithTiming } from '../../../../common/types';
import { setupEnvironment } from '../../helpers';
import { setupValidationTestBed, ValidationTestBed } from './validation.helpers';
-describe(' timing validation', () => {
+// FLAKY: https://github.com/elastic/kibana/issues/115307
+describe.skip(' timing validation', () => {
let testBed: ValidationTestBed;
let actions: ValidationTestBed['actions'];
const { server, httpRequestsMockHelpers } = setupEnvironment();
diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/policy_list/components/policy_table.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/policy_list/components/policy_table.tsx
index d6d030c3ec7339..61ce87860d8972 100644
--- a/x-pack/plugins/index_lifecycle_management/public/application/sections/policy_list/components/policy_table.tsx
+++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/policy_list/components/policy_table.tsx
@@ -191,7 +191,9 @@ export const PolicyTable: React.FunctionComponent = ({ policies }) => {
direction: 'asc',
},
}}
- search={{ box: { incremental: true } }}
+ search={{
+ box: { incremental: true, 'data-test-subj': 'ilmSearchBar' },
+ }}
tableLayout="auto"
items={policies}
columns={columns}
diff --git a/x-pack/plugins/index_management/common/constants/plugin.ts b/x-pack/plugins/index_management/common/constants/plugin.ts
index ad57398000426b..060d42ca26b023 100644
--- a/x-pack/plugins/index_management/common/constants/plugin.ts
+++ b/x-pack/plugins/index_management/common/constants/plugin.ts
@@ -22,4 +22,4 @@ export const PLUGIN = {
// "PluginInitializerContext.env.packageInfo.version". In some cases it is not possible
// to dynamically inject that version without a huge refactor on the code base.
// We will then keep this single constant to declare on which major branch we are.
-export const MAJOR_VERSION = '8.0.0';
+export const MAJOR_VERSION = '8.1.0';
diff --git a/x-pack/plugins/infra/common/source_configuration/source_configuration.ts b/x-pack/plugins/infra/common/source_configuration/source_configuration.ts
index 436432e9f0caf6..257cccc86595cd 100644
--- a/x-pack/plugins/infra/common/source_configuration/source_configuration.ts
+++ b/x-pack/plugins/infra/common/source_configuration/source_configuration.ts
@@ -49,8 +49,6 @@ export const TimestampFromString = new rt.Type(
export const sourceConfigurationConfigFilePropertiesRT = rt.type({
sources: rt.type({
default: rt.partial({
- logAlias: rt.string, // Cannot be deprecated until 8.0.0. Will be converted to an indexName reference.
- metricAlias: rt.string,
fields: rt.partial({
timestamp: rt.string,
message: rt.array(rt.string),
diff --git a/x-pack/plugins/infra/server/deprecations.ts b/x-pack/plugins/infra/server/deprecations.ts
index 70131cd96d117c..4c2f5f6a9b3d14 100644
--- a/x-pack/plugins/infra/server/deprecations.ts
+++ b/x-pack/plugins/infra/server/deprecations.ts
@@ -179,8 +179,6 @@ export const configDeprecations: ConfigDeprecationProvider = ({ deprecate }) =>
return completeConfig;
}
),
- deprecate('sources.default.logAlias', '8.0.0'),
- deprecate('sources.default.metricAlias', '8.0.0'),
];
export const getInfraDeprecationsFactory =
diff --git a/x-pack/plugins/infra/server/lib/sources/sources.ts b/x-pack/plugins/infra/server/lib/sources/sources.ts
index 45da4546ad3b82..4d2f0a8c4a1598 100644
--- a/x-pack/plugins/infra/server/lib/sources/sources.ts
+++ b/x-pack/plugins/infra/server/lib/sources/sources.ts
@@ -212,26 +212,7 @@ export class InfraSources {
fold(constant({}), identity)
);
- // NOTE: Legacy logAlias needs converting to a logIndices reference until we can remove
- // config file sources in 8.0.0.
- if (staticSourceConfiguration && staticSourceConfiguration.logAlias) {
- const convertedStaticSourceConfiguration: InfraStaticSourceConfiguration & {
- logAlias?: string;
- } = {
- ...staticSourceConfiguration,
- logIndices: {
- type: 'index_name',
- indexName: staticSourceConfiguration.logAlias,
- },
- };
- delete convertedStaticSourceConfiguration.logAlias;
- return mergeSourceConfiguration(
- defaultSourceConfiguration,
- convertedStaticSourceConfiguration
- );
- } else {
- return mergeSourceConfiguration(defaultSourceConfiguration, staticSourceConfiguration);
- }
+ return mergeSourceConfiguration(defaultSourceConfiguration, staticSourceConfiguration);
}
private async getSavedSourceConfiguration(
diff --git a/x-pack/plugins/infra/server/plugin.ts b/x-pack/plugins/infra/server/plugin.ts
index bf9c5a152058e4..247888fc2ae70b 100644
--- a/x-pack/plugins/infra/server/plugin.ts
+++ b/x-pack/plugins/infra/server/plugin.ts
@@ -51,8 +51,6 @@ export const config: PluginConfigDescriptor = {
schema.object({
default: schema.maybe(
schema.object({
- logAlias: schema.maybe(schema.string()), // NOTE / TODO: Should be deprecated in 8.0.0
- metricAlias: schema.maybe(schema.string()),
fields: schema.maybe(
schema.object({
timestamp: schema.maybe(schema.string()),
diff --git a/x-pack/plugins/ingest_pipelines/kibana.json b/x-pack/plugins/ingest_pipelines/kibana.json
index 800d92b5c97488..889559826f1f1d 100644
--- a/x-pack/plugins/ingest_pipelines/kibana.json
+++ b/x-pack/plugins/ingest_pipelines/kibana.json
@@ -1,6 +1,6 @@
{
"id": "ingestPipelines",
- "version": "8.0.0",
+ "version": "8.1.0",
"server": true,
"ui": true,
"owner": {
diff --git a/x-pack/plugins/lens/public/xy_visualization/__snapshots__/expression.test.tsx.snap b/x-pack/plugins/lens/public/xy_visualization/__snapshots__/expression.test.tsx.snap
index b058c42d8b4d10..6601167e1f83a6 100644
--- a/x-pack/plugins/lens/public/xy_visualization/__snapshots__/expression.test.tsx.snap
+++ b/x-pack/plugins/lens/public/xy_visualization/__snapshots__/expression.test.tsx.snap
@@ -67,6 +67,7 @@ exports[`xy_expression XYChart component it renders area 1`] = `
}
}
tickFormat={[Function]}
+ timeAxisLayerCount={0}
title="c"
/>
{
onClickValue,
onSelectRange,
syncColors: false,
+ useLegacyTimeAxis: false,
};
});
diff --git a/x-pack/plugins/lens/public/xy_visualization/expression.tsx b/x-pack/plugins/lens/public/xy_visualization/expression.tsx
index a3022e830c8615..80e4a8d4dc8f70 100644
--- a/x-pack/plugins/lens/public/xy_visualization/expression.tsx
+++ b/x-pack/plugins/lens/public/xy_visualization/expression.tsx
@@ -31,6 +31,8 @@ import {
LabelOverflowConstraint,
DisplayValueStyle,
RecursivePartial,
+ AxisStyle,
+ GridLineStyle,
ScaleType,
} from '@elastic/charts';
import { I18nProvider } from '@kbn/i18n/react';
@@ -90,6 +92,7 @@ export type XYChartRenderProps = XYChartProps & {
paletteService: PaletteRegistry;
formatFactory: FormatFactory;
timeZone: string;
+ useLegacyTimeAxis: boolean;
minInterval: number | undefined;
interactive?: boolean;
onClickValue: (data: LensFilterEvent['data']) => void;
@@ -130,6 +133,7 @@ export const getXyChartRenderer = (dependencies: {
chartsActiveCursorService: ChartsPluginStart['activeCursor'];
paletteService: PaletteRegistry;
timeZone: string;
+ useLegacyTimeAxis: boolean;
}): ExpressionRenderDefinition => ({
name: 'lens_xy_chart_renderer',
displayName: 'XY chart',
@@ -160,6 +164,7 @@ export const getXyChartRenderer = (dependencies: {
chartsThemeService={dependencies.chartsThemeService}
paletteService={dependencies.paletteService}
timeZone={dependencies.timeZone}
+ useLegacyTimeAxis={dependencies.useLegacyTimeAxis}
minInterval={calculateMinInterval(config)}
interactive={handlers.isInteractive()}
onClickValue={onClickValue}
@@ -235,6 +240,7 @@ export function XYChart({
onSelectRange,
interactive = true,
syncColors,
+ useLegacyTimeAxis,
}: XYChartRenderProps) {
const {
legend,
@@ -320,15 +326,15 @@ export function XYChart({
filteredBarLayers.some((layer) => layer.accessors.length > 1) ||
filteredBarLayers.some((layer) => layer.splitAccessor);
- const isTimeViz = data.dateRange && filteredLayers.every((l) => l.xScaleType === 'time');
+ const isTimeViz = Boolean(data.dateRange && filteredLayers.every((l) => l.xScaleType === 'time'));
const isHistogramViz = filteredLayers.every((l) => l.isHistogram);
const { baseDomain: rawXDomain, extendedDomain: xDomain } = getXDomain(
filteredLayers,
data,
minInterval,
- Boolean(isTimeViz),
- Boolean(isHistogramViz)
+ isTimeViz,
+ isHistogramViz
);
const yAxesMap = {
@@ -555,6 +561,72 @@ export function XYChart({
floatingColumns: legend?.floatingColumns ?? 1,
} as LegendPositionConfig;
+ // todo be moved in the chart plugin
+ const shouldUseNewTimeAxis = isTimeViz && !useLegacyTimeAxis && !shouldRotate;
+
+ const gridLineStyle: RecursivePartial = shouldUseNewTimeAxis
+ ? {
+ visible: gridlinesVisibilitySettings?.x,
+ strokeWidth: 0.1,
+ stroke: darkMode ? 'white' : 'black',
+ }
+ : {
+ visible: gridlinesVisibilitySettings?.x,
+ strokeWidth: 2,
+ };
+ const xAxisStyle: RecursivePartial = shouldUseNewTimeAxis
+ ? {
+ tickLabel: {
+ visible: Boolean(tickLabelsVisibilitySettings?.x),
+ rotation: 0, // rotation is disabled on new time axis
+ fontSize: 11,
+ padding:
+ referenceLinePaddings.bottom != null ? { inner: referenceLinePaddings.bottom } : 0,
+ alignment: {
+ vertical: Position.Bottom,
+ horizontal: Position.Left,
+ },
+ offset: {
+ x: 1.5,
+ y: 0,
+ },
+ },
+ axisLine: {
+ stroke: darkMode ? 'lightgray' : 'darkgray',
+ strokeWidth: 1,
+ },
+ tickLine: {
+ size: 12,
+ strokeWidth: 0.15,
+ stroke: darkMode ? 'white' : 'black',
+ padding: -10,
+ visible: Boolean(tickLabelsVisibilitySettings?.x),
+ },
+ axisTitle: {
+ visible: axisTitlesVisibilitySettings.x,
+ padding:
+ !tickLabelsVisibilitySettings?.x && referenceLinePaddings.bottom != null
+ ? { inner: referenceLinePaddings.bottom }
+ : undefined,
+ },
+ }
+ : {
+ tickLabel: {
+ visible: tickLabelsVisibilitySettings?.x,
+ rotation: labelsOrientation?.x,
+ padding:
+ referenceLinePaddings.bottom != null
+ ? { inner: referenceLinePaddings.bottom }
+ : undefined,
+ },
+ axisTitle: {
+ visible: axisTitlesVisibilitySettings.x,
+ padding:
+ !tickLabelsVisibilitySettings?.x && referenceLinePaddings.bottom != null
+ ? { inner: referenceLinePaddings.bottom }
+ : undefined,
+ },
+ };
return (
safeXAccessorLabelRenderer(d.value),
}}
- allowBrushingLastHistogramBin={Boolean(isTimeViz)}
+ allowBrushingLastHistogramBin={isTimeViz}
rotation={shouldRotate ? 90 : 0}
xDomain={xDomain}
onBrushEnd={interactive ? (brushHandler as BrushEndListener) : undefined}
@@ -618,29 +690,11 @@ export function XYChart({
id="x"
position={shouldRotate ? Position.Left : Position.Bottom}
title={xTitle}
- gridLine={{
- visible: gridlinesVisibilitySettings?.x,
- strokeWidth: 2,
- }}
+ gridLine={gridLineStyle}
hide={filteredLayers[0].hide || !filteredLayers[0].xAccessor}
tickFormat={(d) => safeXAccessorLabelRenderer(d)}
- style={{
- tickLabel: {
- visible: tickLabelsVisibilitySettings?.x,
- rotation: labelsOrientation?.x,
- padding:
- referenceLinePaddings.bottom != null
- ? { inner: referenceLinePaddings.bottom }
- : undefined,
- },
- axisTitle: {
- visible: axisTitlesVisibilitySettings.x,
- padding:
- !tickLabelsVisibilitySettings?.x && referenceLinePaddings.bottom != null
- ? { inner: referenceLinePaddings.bottom }
- : undefined,
- },
- }}
+ style={xAxisStyle}
+ timeAxisLayerCount={shouldUseNewTimeAxis ? 3 : 0}
/>
{yAxesConfiguration.map((axis) => {
diff --git a/x-pack/plugins/lens/public/xy_visualization/index.ts b/x-pack/plugins/lens/public/xy_visualization/index.ts
index f9d48ffaaae37b..d3d461e8f8741e 100644
--- a/x-pack/plugins/lens/public/xy_visualization/index.ts
+++ b/x-pack/plugins/lens/public/xy_visualization/index.ts
@@ -12,6 +12,7 @@ import type { ChartsPluginSetup } from '../../../../../src/plugins/charts/public
import type { LensPluginStartDependencies } from '../plugin';
import { getTimeZone } from '../utils';
import type { FormatFactory } from '../../common';
+import { LEGACY_TIME_AXIS } from '../../../../../src/plugins/charts/common';
export interface XyVisualizationPluginSetupPlugins {
expressions: ExpressionsSetup;
@@ -37,6 +38,7 @@ export class XyVisualization {
chartsActiveCursorService: charts.activeCursor,
paletteService: palettes,
timeZone: getTimeZone(core.uiSettings),
+ useLegacyTimeAxis: core.uiSettings.get(LEGACY_TIME_AXIS),
})
);
return getXyVisualization({ paletteService: palettes, fieldFormats });
diff --git a/x-pack/plugins/maps/common/descriptor_types/source_descriptor_types.ts b/x-pack/plugins/maps/common/descriptor_types/source_descriptor_types.ts
index 285c4043e46c78..e1b5d3e8190b08 100644
--- a/x-pack/plugins/maps/common/descriptor_types/source_descriptor_types.ts
+++ b/x-pack/plugins/maps/common/descriptor_types/source_descriptor_types.ts
@@ -27,6 +27,7 @@ export type AbstractSourceDescriptor = {
export type EMSTMSSourceDescriptor = AbstractSourceDescriptor & {
// id: EMS TMS layer id. Used when !isAutoSelect
isAutoSelect: boolean;
+ lightModeDefault: string;
};
export type EMSFileSourceDescriptor = AbstractSourceDescriptor & {
diff --git a/x-pack/plugins/maps/common/migrations/set_ems_tms_default_modes.test.ts b/x-pack/plugins/maps/common/migrations/set_ems_tms_default_modes.test.ts
new file mode 100644
index 00000000000000..5aab4e24c8ba66
--- /dev/null
+++ b/x-pack/plugins/maps/common/migrations/set_ems_tms_default_modes.test.ts
@@ -0,0 +1,58 @@
+/*
+ * 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 { setEmsTmsDefaultModes } from './set_ems_tms_default_modes';
+
+describe('setEmsTmsDefaultModes', () => {
+ test('Should handle missing layerListJSON attribute', () => {
+ const attributes = {
+ title: 'my map',
+ };
+ expect(setEmsTmsDefaultModes({ attributes })).toEqual({
+ title: 'my map',
+ });
+ });
+
+ test('Should add lightModeDefault to existing EMS_TMS source descriptors', () => {
+ const layerListJSON = JSON.stringify([
+ {
+ sourceDescriptor: {
+ type: 'EMS_TMS',
+ },
+ },
+ ]);
+ const attributes = {
+ title: 'my map',
+ layerListJSON,
+ };
+ expect(setEmsTmsDefaultModes({ attributes })).toEqual({
+ title: 'my map',
+ layerListJSON: '[{"sourceDescriptor":{"type":"EMS_TMS","lightModeDefault":"road_map"}}]',
+ });
+ });
+
+ // test edge case where sample data maps set lightModeDefault but still run migration
+ test('Should not change lightModeDefault if provided', () => {
+ const layerListJSON = JSON.stringify([
+ {
+ sourceDescriptor: {
+ type: 'EMS_TMS',
+ lightModeDefault: 'road_map_desaturated',
+ },
+ },
+ ]);
+ const attributes = {
+ title: 'my map',
+ layerListJSON,
+ };
+ expect(setEmsTmsDefaultModes({ attributes })).toEqual({
+ title: 'my map',
+ layerListJSON:
+ '[{"sourceDescriptor":{"type":"EMS_TMS","lightModeDefault":"road_map_desaturated"}}]',
+ });
+ });
+});
diff --git a/x-pack/plugins/maps/common/migrations/set_ems_tms_default_modes.ts b/x-pack/plugins/maps/common/migrations/set_ems_tms_default_modes.ts
new file mode 100644
index 00000000000000..94dbd8741add7f
--- /dev/null
+++ b/x-pack/plugins/maps/common/migrations/set_ems_tms_default_modes.ts
@@ -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 { SOURCE_TYPES } from '../constants';
+import { LayerDescriptor, EMSTMSSourceDescriptor } from '../descriptor_types';
+import { MapSavedObjectAttributes } from '../map_saved_object_type';
+
+// LightModeDefault added to EMSTMSSourceDescriptor in 8.0.0
+// to avoid changing auto selected light mode tiles for maps created < 8.0.0
+// < 8.0.0 did not specify defaults and used bright for light mode
+// > 8.0.0 changed default light mode from bright to desaturated
+export function setEmsTmsDefaultModes({
+ attributes,
+}: {
+ attributes: MapSavedObjectAttributes;
+}): MapSavedObjectAttributes {
+ if (!attributes || !attributes.layerListJSON) {
+ return attributes;
+ }
+
+ const layerList: LayerDescriptor[] = JSON.parse(attributes.layerListJSON);
+ layerList.forEach((layerDescriptor: LayerDescriptor) => {
+ if (layerDescriptor.sourceDescriptor?.type === SOURCE_TYPES.EMS_TMS) {
+ const sourceDescriptor = layerDescriptor.sourceDescriptor as EMSTMSSourceDescriptor;
+ // auto select bright tiles for EMS_TMS layers created before 8.0.0
+ if (!sourceDescriptor.lightModeDefault) {
+ sourceDescriptor.lightModeDefault = 'road_map';
+ }
+ }
+ });
+
+ return {
+ ...attributes,
+ layerListJSON: JSON.stringify(layerList),
+ };
+}
diff --git a/x-pack/plugins/maps/public/classes/layers/create_basemap_layer_descriptor.test.ts b/x-pack/plugins/maps/public/classes/layers/create_basemap_layer_descriptor.test.ts
index 59ff7e5e6616be..cf3d8705380043 100644
--- a/x-pack/plugins/maps/public/classes/layers/create_basemap_layer_descriptor.test.ts
+++ b/x-pack/plugins/maps/public/classes/layers/create_basemap_layer_descriptor.test.ts
@@ -85,6 +85,7 @@ describe('EMS is enabled', () => {
source: undefined,
sourceDescriptor: {
isAutoSelect: true,
+ lightModeDefault: 'road_map_desaturated',
type: 'EMS_TMS',
},
style: { type: 'TILE' },
diff --git a/x-pack/plugins/maps/public/classes/sources/ems_tms_source/ems_tms_source.js b/x-pack/plugins/maps/public/classes/sources/ems_tms_source/ems_tms_source.js
index fec10501209602..2acb0578f6152e 100644
--- a/x-pack/plugins/maps/public/classes/sources/ems_tms_source/ems_tms_source.js
+++ b/x-pack/plugins/maps/public/classes/sources/ems_tms_source/ems_tms_source.js
@@ -43,7 +43,11 @@ export class EMSTMSSource extends AbstractTMSSource {
type: SOURCE_TYPES.EMS_TMS,
id: descriptor.id,
isAutoSelect:
- typeof descriptor.isAutoSelect !== 'undefined' ? !!descriptor.isAutoSelect : false,
+ typeof descriptor.isAutoSelect !== 'undefined' ? descriptor.isAutoSelect : false,
+ lightModeDefault:
+ typeof descriptor.lightModeDefault !== 'undefined'
+ ? descriptor.lightModeDefault
+ : getEmsTileLayerId().desaturated,
};
}
@@ -144,12 +148,11 @@ export class EMSTMSSource extends AbstractTMSSource {
}
getTileLayerId() {
- if (!this._descriptor.isAutoSelect) {
+ if (!this._descriptor.isAutoSelect && this._descriptor.id) {
return this._descriptor.id;
}
- const emsTileLayerId = getEmsTileLayerId();
- return getIsDarkMode() ? emsTileLayerId.dark : emsTileLayerId.bright;
+ return getIsDarkMode() ? getEmsTileLayerId().dark : this._descriptor.lightModeDefault;
}
async getLicensedFeatures() {
diff --git a/x-pack/plugins/maps/public/classes/sources/ems_tms_source/ems_tms_source.test.js b/x-pack/plugins/maps/public/classes/sources/ems_tms_source/ems_tms_source.test.js
index 8998e895f6541f..833e4b0fff95ec 100644
--- a/x-pack/plugins/maps/public/classes/sources/ems_tms_source/ems_tms_source.test.js
+++ b/x-pack/plugins/maps/public/classes/sources/ems_tms_source/ems_tms_source.test.js
@@ -5,6 +5,18 @@
* 2.0.
*/
+jest.mock('../../../kibana_services', () => {
+ return {
+ getEmsTileLayerId: () => {
+ return {
+ bright: 'road_map',
+ desaturated: 'road_map_desaturated',
+ dark: 'dark_map',
+ };
+ },
+ };
+});
+
jest.mock('../../../util', () => {
return {
getEmsTmsServices: () => {
diff --git a/x-pack/plugins/maps/public/classes/sources/ems_tms_source/tile_service_select.tsx b/x-pack/plugins/maps/public/classes/sources/ems_tms_source/tile_service_select.tsx
index e4a6fed934b8d4..60c047b13bb7ad 100644
--- a/x-pack/plugins/maps/public/classes/sources/ems_tms_source/tile_service_select.tsx
+++ b/x-pack/plugins/maps/public/classes/sources/ems_tms_source/tile_service_select.tsx
@@ -12,7 +12,7 @@ import { i18n } from '@kbn/i18n';
import { getEmsTmsServices } from '../../../util';
import { getEmsUnavailableMessage } from '../../../components/ems_unavailable_message';
-export const AUTO_SELECT = 'auto_select';
+const AUTO_SELECT = 'auto_select';
export interface EmsTmsSourceConfig {
id: string | null;
diff --git a/x-pack/plugins/maps/server/embeddable_migrations.ts b/x-pack/plugins/maps/server/embeddable_migrations.ts
index 2a53198d8d247a..a49e776d4fe02f 100644
--- a/x-pack/plugins/maps/server/embeddable_migrations.ts
+++ b/x-pack/plugins/maps/server/embeddable_migrations.ts
@@ -8,12 +8,13 @@
import type { SerializableRecord } from '@kbn/utility-types';
import { MapSavedObjectAttributes } from '../common/map_saved_object_type';
import { moveAttribution } from '../common/migrations/move_attribution';
+import { setEmsTmsDefaultModes } from '../common/migrations/set_ems_tms_default_modes';
/*
* Embeddables such as Maps, Lens, and Visualize can be embedded by value or by reference on a dashboard.
* To ensure that any migrations (>7.12) are run correctly in both cases,
* the migration function must be registered as both a saved object migration and an embeddable migration
-
+ *
* This is the embeddable migration registry.
*/
export const embeddableMigrations = {
@@ -23,4 +24,10 @@ export const embeddableMigrations = {
attributes: moveAttribution(state as { attributes: MapSavedObjectAttributes }),
} as SerializableRecord;
},
+ '8.0.0': (state: SerializableRecord) => {
+ return {
+ ...state,
+ attributes: setEmsTmsDefaultModes(state as { attributes: MapSavedObjectAttributes }),
+ } as SerializableRecord;
+ },
};
diff --git a/x-pack/plugins/maps/server/sample_data/ecommerce_saved_objects.js b/x-pack/plugins/maps/server/sample_data/ecommerce_saved_objects.js
index a0ac4db734bd7e..e778b9e4162302 100644
--- a/x-pack/plugins/maps/server/sample_data/ecommerce_saved_objects.js
+++ b/x-pack/plugins/maps/server/sample_data/ecommerce_saved_objects.js
@@ -15,6 +15,7 @@ const layerList = [
sourceDescriptor: {
type: 'EMS_TMS',
isAutoSelect: true,
+ lightModeDefault: 'road_map_desaturated',
},
visible: true,
style: {},
diff --git a/x-pack/plugins/maps/server/sample_data/flights_saved_objects.js b/x-pack/plugins/maps/server/sample_data/flights_saved_objects.js
index 4e9915623d7c7d..645eb0a90e5601 100644
--- a/x-pack/plugins/maps/server/sample_data/flights_saved_objects.js
+++ b/x-pack/plugins/maps/server/sample_data/flights_saved_objects.js
@@ -14,6 +14,7 @@ const layerList = [
sourceDescriptor: {
type: 'EMS_TMS',
isAutoSelect: true,
+ lightModeDefault: 'road_map_desaturated',
},
visible: true,
style: {},
diff --git a/x-pack/plugins/maps/server/sample_data/web_logs_saved_objects.js b/x-pack/plugins/maps/server/sample_data/web_logs_saved_objects.js
index 984b9de7ac2b6c..5cc460160a676e 100644
--- a/x-pack/plugins/maps/server/sample_data/web_logs_saved_objects.js
+++ b/x-pack/plugins/maps/server/sample_data/web_logs_saved_objects.js
@@ -15,6 +15,7 @@ const layerList = [
sourceDescriptor: {
type: 'EMS_TMS',
isAutoSelect: true,
+ lightModeDefault: 'road_map_desaturated',
},
visible: true,
style: {},
diff --git a/x-pack/plugins/maps/server/saved_objects/saved_object_migrations.js b/x-pack/plugins/maps/server/saved_objects/saved_object_migrations.js
index 8866ebb6b3de39..5fc15e89297143 100644
--- a/x-pack/plugins/maps/server/saved_objects/saved_object_migrations.js
+++ b/x-pack/plugins/maps/server/saved_objects/saved_object_migrations.js
@@ -17,12 +17,13 @@ import { removeBoundsFromSavedObject } from '../../common/migrations/remove_boun
import { setDefaultAutoFitToBounds } from '../../common/migrations/set_default_auto_fit_to_bounds';
import { addTypeToTermJoin } from '../../common/migrations/add_type_to_termjoin';
import { moveAttribution } from '../../common/migrations/move_attribution';
+import { setEmsTmsDefaultModes } from '../../common/migrations/set_ems_tms_default_modes';
/*
* Embeddables such as Maps, Lens, and Visualize can be embedded by value or by reference on a dashboard.
* To ensure that any migrations (>7.12) are run correctly in both cases,
* the migration function must be registered as both a saved object migration and an embeddable migration
-
+ *
* This is the saved object migration registry.
*/
export const savedObjectMigrations = {
@@ -104,6 +105,14 @@ export const savedObjectMigrations = {
'7.14.0': (doc) => {
const attributes = moveAttribution(doc);
+ return {
+ ...doc,
+ attributes,
+ };
+ },
+ '8.0.0': (doc) => {
+ const attributes = setEmsTmsDefaultModes(doc);
+
return {
...doc,
attributes,
diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/__mocks__/analytics_list_item.json b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/__mocks__/analytics_list_item.json
index 20343755f7f0f1..1b7d353d9f3038 100644
--- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/__mocks__/analytics_list_item.json
+++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/__mocks__/analytics_list_item.json
@@ -22,7 +22,7 @@
},
"model_memory_limit": "50mb",
"create_time": 1568974998023,
- "version": "8.0.0"
+ "version": "8.1.0"
},
"id": "fq_outlier_1222",
"checkpointing": {},
diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/components/forecasting_modal/forecasts_list.js b/x-pack/plugins/ml/public/application/timeseriesexplorer/components/forecasting_modal/forecasts_list.js
index 1854982c8db0bf..7f9fcc7bc55170 100644
--- a/x-pack/plugins/ml/public/application/timeseriesexplorer/components/forecasting_modal/forecasts_list.js
+++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/components/forecasting_modal/forecasts_list.js
@@ -78,6 +78,12 @@ function getColumns(viewForecast) {
// TODO - add in ml-info-icon to the h3 element,
// then remove tooltip and inline style.
export function ForecastsList({ forecasts, viewForecast }) {
+ const getRowProps = (item) => {
+ return {
+ 'data-test-subj': `mlForecastsListRow row-${item.rowId}`,
+ };
+ };
+
return (
);
diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/components/timeseries_chart/timeseries_chart.js b/x-pack/plugins/ml/public/application/timeseriesexplorer/components/timeseries_chart/timeseries_chart.js
index 87131583e44eb4..cad5bb68fb62b7 100644
--- a/x-pack/plugins/ml/public/application/timeseriesexplorer/components/timeseries_chart/timeseries_chart.js
+++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/components/timeseries_chart/timeseries_chart.js
@@ -547,9 +547,18 @@ class TimeseriesChartIntl extends Component {
// Create the path elements for the forecast value line and bounds area.
if (contextForecastData) {
- fcsGroup.append('path').attr('class', 'area forecast');
- fcsGroup.append('path').attr('class', 'values-line forecast');
- fcsGroup.append('g').attr('class', 'focus-chart-markers forecast');
+ fcsGroup
+ .append('path')
+ .attr('class', 'area forecast')
+ .attr('data-test-subj', 'mlForecastArea');
+ fcsGroup
+ .append('path')
+ .attr('class', 'values-line forecast')
+ .attr('data-test-subj', 'mlForecastValuesline');
+ fcsGroup
+ .append('g')
+ .attr('class', 'focus-chart-markers forecast')
+ .attr('data-test-subj', 'mlForecastMarkers');
}
fcsGroup
diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer.js b/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer.js
index 9b8770350909ea..e4d7fc457de0b7 100644
--- a/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer.js
+++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer.js
@@ -1170,9 +1170,13 @@ export class TimeSeriesExplorer extends React.Component {
+ {i18n.translate('xpack.ml.timeSeriesExplorer.showForecastLabel', {
+ defaultMessage: 'show forecast',
+ })}
+
+ }
checked={showForecast}
onChange={this.toggleShowForecastHandler}
/>
diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/report_metric_options.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/report_metric_options.tsx
index 496e7a10f9c447..eca18f0eb0dd40 100644
--- a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/report_metric_options.tsx
+++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/report_metric_options.tsx
@@ -13,6 +13,8 @@ import {
EuiListGroup,
EuiListGroupItem,
EuiBadge,
+ EuiText,
+ EuiLoadingSpinner,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
@@ -33,7 +35,7 @@ export function ReportMetricOptions({ seriesId, series, seriesConfig }: Props) {
const [showOptions, setShowOptions] = useState(false);
const metricOptions = seriesConfig?.metricOptions;
- const { indexPatterns } = useAppIndexPatternContext();
+ const { indexPatterns, loading } = useAppIndexPatternContext();
const onChange = (value?: string) => {
setSeries(seriesId, {
@@ -78,6 +80,10 @@ export function ReportMetricOptions({ seriesId, series, seriesConfig }: Props) {
};
});
+ if (!indexPattern && !loading) {
+ return {NO_DATA_AVAILABLE};
+ }
+
return (
<>
{!series.selectedMetricField && (
@@ -88,6 +94,7 @@ export function ReportMetricOptions({ seriesId, series, seriesConfig }: Props) {
onClick={() => setShowOptions((prevState) => !prevState)}
fill
size="s"
+ isLoading={!indexPattern && loading}
>
{SELECT_REPORT_METRIC_LABEL}
@@ -107,19 +114,23 @@ export function ReportMetricOptions({ seriesId, series, seriesConfig }: Props) {
)}
- {series.selectedMetricField && (
- onChange(undefined)}
- iconOnClickAriaLabel={REMOVE_REPORT_METRIC_LABEL}
- >
- {
- seriesConfig?.metricOptions?.find((option) => option.id === series.selectedMetricField)
- ?.label
- }
-
- )}
+ {series.selectedMetricField &&
+ (indexPattern && !loading ? (
+ onChange(undefined)}
+ iconOnClickAriaLabel={REMOVE_REPORT_METRIC_LABEL}
+ >
+ {
+ seriesConfig?.metricOptions?.find(
+ (option) => option.id === series.selectedMetricField
+ )?.label
+ }
+
+ ) : (
+
+ ))}
>
);
}
@@ -137,3 +148,7 @@ const REMOVE_REPORT_METRIC_LABEL = i18n.translate(
defaultMessage: 'Remove report metric',
}
);
+
+const NO_DATA_AVAILABLE = i18n.translate('xpack.observability.expView.seriesEditor.noData', {
+ defaultMessage: 'No data available',
+});
diff --git a/x-pack/plugins/painless_lab/kibana.json b/x-pack/plugins/painless_lab/kibana.json
index 7c71d4bdb4b761..1f59bf30bb761f 100644
--- a/x-pack/plugins/painless_lab/kibana.json
+++ b/x-pack/plugins/painless_lab/kibana.json
@@ -1,6 +1,6 @@
{
"id": "painlessLab",
- "version": "8.0.0",
+ "version": "8.1.0",
"kibanaVersion": "kibana",
"owner": {
"name": "Stack Management",
diff --git a/x-pack/plugins/remote_clusters/common/constants.ts b/x-pack/plugins/remote_clusters/common/constants.ts
index 5a36924b26433c..072d6d437b8b99 100644
--- a/x-pack/plugins/remote_clusters/common/constants.ts
+++ b/x-pack/plugins/remote_clusters/common/constants.ts
@@ -20,7 +20,7 @@ export const PLUGIN = {
},
};
-export const MAJOR_VERSION = '8.0.0';
+export const MAJOR_VERSION = '8.1.0';
export const API_BASE_PATH = '/api/remote_clusters';
diff --git a/x-pack/plugins/reporting/server/routes/diagnostic/browser.test.ts b/x-pack/plugins/reporting/server/routes/diagnostic/browser.test.ts
index 7677f37702f0d8..7b4cc2008a6769 100644
--- a/x-pack/plugins/reporting/server/routes/diagnostic/browser.test.ts
+++ b/x-pack/plugins/reporting/server/routes/diagnostic/browser.test.ts
@@ -28,7 +28,8 @@ type SetupServerReturn = UnwrapPromise>;
const devtoolMessage = 'DevTools listening on (ws://localhost:4000)';
const fontNotFoundMessage = 'Could not find the default font';
-describe('POST /diagnose/browser', () => {
+// FLAKY: https://github.com/elastic/kibana/issues/89369
+describe.skip('POST /diagnose/browser', () => {
jest.setTimeout(6000);
const reportingSymbol = Symbol('reporting');
const mockLogger = createMockLevelLogger();
diff --git a/x-pack/plugins/security_solution/cypress/integration/detection_rules/event_correlation_rule.spec.ts b/x-pack/plugins/security_solution/cypress/integration/detection_rules/event_correlation_rule.spec.ts
index 171d224cc32d35..10f556a11bf602 100644
--- a/x-pack/plugins/security_solution/cypress/integration/detection_rules/event_correlation_rule.spec.ts
+++ b/x-pack/plugins/security_solution/cypress/integration/detection_rules/event_correlation_rule.spec.ts
@@ -70,7 +70,7 @@ import { loginAndWaitForPageWithoutDateRange } from '../../tasks/login';
import { ALERTS_URL } from '../../urls/navigation';
-describe('Detection rules, EQL', () => {
+describe.skip('Detection rules, EQL', () => {
const expectedUrls = getEqlRule().referenceUrls.join('');
const expectedFalsePositives = getEqlRule().falsePositivesExamples.join('');
const expectedTags = getEqlRule().tags.join('');
@@ -169,7 +169,7 @@ describe('Detection rules, EQL', () => {
});
});
-describe('Detection rules, sequence EQL', () => {
+describe.skip('Detection rules, sequence EQL', () => {
const expectedNumberOfRules = 1;
const expectedNumberOfSequenceAlerts = '1 alert';
diff --git a/x-pack/plugins/security_solution/cypress/integration/exceptions/from_alert.spec.ts b/x-pack/plugins/security_solution/cypress/integration/exceptions/from_alert.spec.ts
index 002aa0bbc2b1ea..cea290eeef17be 100644
--- a/x-pack/plugins/security_solution/cypress/integration/exceptions/from_alert.spec.ts
+++ b/x-pack/plugins/security_solution/cypress/integration/exceptions/from_alert.spec.ts
@@ -8,7 +8,7 @@
import { getException } from '../../objects/exception';
import { getNewRule } from '../../objects/rule';
-import { ALERTS_COUNT, NUMBER_OF_ALERTS } from '../../screens/alerts';
+import { ALERTS_COUNT, EMPTY_ALERT_TABLE, NUMBER_OF_ALERTS } from '../../screens/alerts';
import { RULE_STATUS } from '../../screens/create_new_rule';
import {
@@ -31,13 +31,12 @@ import {
removeException,
waitForTheRuleToBeExecuted,
} from '../../tasks/rule_details';
-import { refreshPage } from '../../tasks/security_header';
import { ALERTS_URL } from '../../urls/navigation';
import { cleanKibana } from '../../tasks/common';
-describe('From alert', () => {
- const NUMBER_OF_AUDITBEAT_EXCEPTIONS_ALERTS = '1';
+describe.skip('From alert', () => {
+ const NUMBER_OF_AUDITBEAT_EXCEPTIONS_ALERTS = '1 alert';
beforeEach(() => {
cleanKibana();
@@ -53,7 +52,6 @@ describe('From alert', () => {
activatesRule();
waitForTheRuleToBeExecuted();
waitForAlertsToPopulate();
- refreshPage();
cy.get(ALERTS_COUNT).should('exist');
cy.get(NUMBER_OF_ALERTS).should('have.text', NUMBER_OF_AUDITBEAT_EXCEPTIONS_ALERTS);
@@ -64,36 +62,30 @@ describe('From alert', () => {
esArchiverUnload('auditbeat_for_exceptions2');
});
- // TODO: Unskip the test when `https://github.com/elastic/kibana/issues/108244` it is fixed
- it.skip('Creates an exception and deletes it', () => {
+ it('Creates an exception and deletes it', () => {
addExceptionFromFirstAlert();
addsException(getException());
esArchiverLoad('auditbeat_for_exceptions2');
- cy.get(ALERTS_COUNT).should('exist');
- cy.get(NUMBER_OF_ALERTS).should('have.text', '0 alerts');
+ cy.get(EMPTY_ALERT_TABLE).should('exist');
goToClosedAlerts();
- refreshPage();
cy.get(ALERTS_COUNT).should('exist');
- cy.get(NUMBER_OF_ALERTS).should('have.text', `${NUMBER_OF_AUDITBEAT_EXCEPTIONS_ALERTS} alerts`);
+ cy.get(NUMBER_OF_ALERTS).should('have.text', `${NUMBER_OF_AUDITBEAT_EXCEPTIONS_ALERTS}`);
goToOpenedAlerts();
waitForTheRuleToBeExecuted();
- refreshPage();
- cy.get(ALERTS_COUNT).should('exist');
- cy.get(NUMBER_OF_ALERTS).should('have.text', '0 alerts');
+ cy.get(EMPTY_ALERT_TABLE).should('exist');
goToExceptionsTab();
removeException();
goToAlertsTab();
waitForTheRuleToBeExecuted();
waitForAlertsToPopulate();
- refreshPage();
cy.get(ALERTS_COUNT).should('exist');
- cy.get(NUMBER_OF_ALERTS).should('have.text', `${NUMBER_OF_AUDITBEAT_EXCEPTIONS_ALERTS} alerts`);
+ cy.get(NUMBER_OF_ALERTS).should('have.text', `${NUMBER_OF_AUDITBEAT_EXCEPTIONS_ALERTS}`);
});
});
diff --git a/x-pack/plugins/security_solution/cypress/integration/exceptions/from_rule.spec.ts b/x-pack/plugins/security_solution/cypress/integration/exceptions/from_rule.spec.ts
index c4e1d882d1853d..4af6467e5d33c2 100644
--- a/x-pack/plugins/security_solution/cypress/integration/exceptions/from_rule.spec.ts
+++ b/x-pack/plugins/security_solution/cypress/integration/exceptions/from_rule.spec.ts
@@ -8,7 +8,7 @@
import { getException } from '../../objects/exception';
import { getNewRule } from '../../objects/rule';
-import { ALERTS_COUNT, NUMBER_OF_ALERTS } from '../../screens/alerts';
+import { ALERTS_COUNT, EMPTY_ALERT_TABLE, NUMBER_OF_ALERTS } from '../../screens/alerts';
import { RULE_STATUS } from '../../screens/create_new_rule';
import {
@@ -35,7 +35,7 @@ import { refreshPage } from '../../tasks/security_header';
import { ALERTS_URL } from '../../urls/navigation';
import { cleanKibana } from '../../tasks/common';
-describe('From rule', () => {
+describe.skip('From rule', () => {
const NUMBER_OF_AUDITBEAT_EXCEPTIONS_ALERTS = '1';
beforeEach(() => {
cleanKibana();
@@ -54,7 +54,7 @@ describe('From rule', () => {
refreshPage();
cy.get(ALERTS_COUNT).should('exist');
- cy.get(NUMBER_OF_ALERTS).should('have.text', `${NUMBER_OF_AUDITBEAT_EXCEPTIONS_ALERTS} alerts`);
+ cy.get(NUMBER_OF_ALERTS).should('have.text', `${NUMBER_OF_AUDITBEAT_EXCEPTIONS_ALERTS} alert`);
});
afterEach(() => {
@@ -62,40 +62,32 @@ describe('From rule', () => {
esArchiverUnload('auditbeat_for_exceptions2');
});
- // TODO: Unskip the test when `https://github.com/elastic/kibana/issues/108244` it is fixed
- it.skip('Creates an exception and deletes it', () => {
+ it('Creates an exception and deletes it', () => {
goToExceptionsTab();
addsExceptionFromRuleSettings(getException());
esArchiverLoad('auditbeat_for_exceptions2');
waitForTheRuleToBeExecuted();
goToAlertsTab();
- refreshPage();
- cy.get(ALERTS_COUNT).should('exist');
- cy.get(NUMBER_OF_ALERTS).should('have.text', '0 alerts');
+ cy.get(EMPTY_ALERT_TABLE).should('exist');
goToClosedAlerts();
- refreshPage();
cy.get(ALERTS_COUNT).should('exist');
- cy.get(NUMBER_OF_ALERTS).should('have.text', `${NUMBER_OF_AUDITBEAT_EXCEPTIONS_ALERTS} alerts`);
+ cy.get(NUMBER_OF_ALERTS).should('have.text', `${NUMBER_OF_AUDITBEAT_EXCEPTIONS_ALERTS} alert`);
goToOpenedAlerts();
waitForTheRuleToBeExecuted();
- refreshPage();
- cy.get(ALERTS_COUNT).should('exist');
- cy.get(NUMBER_OF_ALERTS).should('have.text', '0 alerts');
+ cy.get(EMPTY_ALERT_TABLE).should('exist');
goToExceptionsTab();
removeException();
- refreshPage();
goToAlertsTab();
waitForTheRuleToBeExecuted();
waitForAlertsToPopulate();
- refreshPage();
cy.get(ALERTS_COUNT).should('exist');
- cy.get(NUMBER_OF_ALERTS).should('have.text', `${NUMBER_OF_AUDITBEAT_EXCEPTIONS_ALERTS} alerts`);
+ cy.get(NUMBER_OF_ALERTS).should('have.text', `${NUMBER_OF_AUDITBEAT_EXCEPTIONS_ALERTS} alert`);
});
});
diff --git a/x-pack/plugins/security_solution/cypress/screens/alerts.ts b/x-pack/plugins/security_solution/cypress/screens/alerts.ts
index 01848f42078465..a46f65acaf971f 100644
--- a/x-pack/plugins/security_solution/cypress/screens/alerts.ts
+++ b/x-pack/plugins/security_solution/cypress/screens/alerts.ts
@@ -34,6 +34,8 @@ export const CLOSE_SELECTED_ALERTS_BTN = '[data-test-subj="close-alert-status"]'
export const CLOSED_ALERTS_FILTER_BTN = '[data-test-subj="closedAlerts"]';
+export const EMPTY_ALERT_TABLE = '[data-test-subj="tGridEmptyState"]';
+
export const EXPAND_ALERT_BTN = '[data-test-subj="expand-event"]';
export const ACKNOWLEDGED_ALERTS_FILTER_BTN = '[data-test-subj="acknowledgedAlerts"]';
diff --git a/x-pack/plugins/security_solution/cypress/tasks/alerts.ts b/x-pack/plugins/security_solution/cypress/tasks/alerts.ts
index 067c9957189b9e..220c0fbdaa4cf4 100644
--- a/x-pack/plugins/security_solution/cypress/tasks/alerts.ts
+++ b/x-pack/plugins/security_solution/cypress/tasks/alerts.ts
@@ -34,7 +34,7 @@ import {
} from '../screens/alerts_details';
export const addExceptionFromFirstAlert = () => {
- cy.get(TIMELINE_CONTEXT_MENU_BTN).first().click();
+ cy.get(TIMELINE_CONTEXT_MENU_BTN).first().click({ force: true });
cy.get(ADD_EXCEPTION_BTN).click();
};
diff --git a/x-pack/plugins/security_solution/public/common/components/user_privileges/endpoint/use_endpoint_privileges.ts b/x-pack/plugins/security_solution/public/common/components/user_privileges/endpoint/use_endpoint_privileges.ts
index 36f02d22487fc4..448cb215941deb 100644
--- a/x-pack/plugins/security_solution/public/common/components/user_privileges/endpoint/use_endpoint_privileges.ts
+++ b/x-pack/plugins/security_solution/public/common/components/user_privileges/endpoint/use_endpoint_privileges.ts
@@ -9,6 +9,7 @@ import { useEffect, useMemo, useRef, useState } from 'react';
import { useCurrentUser, useHttp } from '../../../lib/kibana';
import { appRoutesService, CheckPermissionsResponse } from '../../../../../../fleet/common';
import { useLicense } from '../../../hooks/use_license';
+import { Immutable } from '../../../../../common/endpoint/types';
export interface EndpointPrivileges {
loading: boolean;
@@ -30,7 +31,7 @@ export interface EndpointPrivileges {
* **NOTE:** Consider using `usePrivileges().endpointPrivileges` instead of this hook in order
* to keep API calls to a minimum.
*/
-export const useEndpointPrivileges = (): EndpointPrivileges => {
+export const useEndpointPrivileges = (): Immutable => {
const http = useHttp();
const user = useCurrentUser();
const isMounted = useRef(true);
@@ -66,7 +67,7 @@ export const useEndpointPrivileges = (): EndpointPrivileges => {
}, [user?.roles]);
const privileges = useMemo(() => {
- const privilegeList: EndpointPrivileges = {
+ const privilegeList: EndpointPrivileges = Object.freeze({
loading: !fleetCheckDone || !user,
canAccessFleet,
canAccessEndpointManagement: canAccessFleet && isSuperUser,
@@ -75,7 +76,7 @@ export const useEndpointPrivileges = (): EndpointPrivileges => {
// FIXME: Remove usages of the property below
/** @deprecated */
isPlatinumPlus: isPlatinumPlusLicense,
- };
+ });
return privilegeList;
}, [canAccessFleet, fleetCheckDone, isSuperUser, user, isPlatinumPlusLicense]);
diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.tsx
index 6b5d6f03aca286..6acc48c55c6e3a 100644
--- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.tsx
+++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.tsx
@@ -10,12 +10,7 @@ import { i18n } from '@kbn/i18n';
import { useLocation } from 'react-router-dom';
import { EuiCallOut, EuiLoadingSpinner, EuiPageTemplate } from '@elastic/eui';
import { usePolicyDetailsSelector } from './policy_hooks';
-import {
- policyDetails,
- agentStatusSummary,
- isLoading,
- apiError,
-} from '../store/policy_details/selectors';
+import { policyDetails, agentStatusSummary, apiError } from '../store/policy_details/selectors';
import { AgentsSummary } from './agents_summary';
import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features';
import { PolicyTabs } from './tabs';
@@ -39,7 +34,6 @@ export const PolicyDetails = React.memo(() => {
const { getAppUrl } = useAppUrl();
// Store values
- const loading = usePolicyDetailsSelector(isLoading);
const policyApiError = usePolicyDetailsSelector(apiError);
const policyItem = usePolicyDetailsSelector(policyDetails);
const policyAgentStatusSummary = usePolicyDetailsSelector(agentStatusSummary);
@@ -90,24 +84,24 @@ export const PolicyDetails = React.memo(() => {
);
const pageBody: React.ReactNode = useMemo(() => {
- if (loading) {
+ if (policyApiError) {
return (
-
+
+ {policyApiError?.message}
+
);
}
- if (policyApiError) {
+ if (!policyItem) {
return (
-
- {policyApiError?.message}
-
+
);
}
@@ -118,7 +112,7 @@ export const PolicyDetails = React.memo(() => {
}
return ;
- }, [isTrustedAppsByPolicyEnabled, loading, policyApiError]);
+ }, [isTrustedAppsByPolicyEnabled, policyApiError, policyItem]);
return (
;
};
export interface PivotConfigDefinition {
diff --git a/x-pack/plugins/transform/public/app/common/request.ts b/x-pack/plugins/transform/public/app/common/request.ts
index 8f8341260bd7eb..184e3d31e89d21 100644
--- a/x-pack/plugins/transform/public/app/common/request.ts
+++ b/x-pack/plugins/transform/public/app/common/request.ts
@@ -242,6 +242,7 @@ export const getCreateTransformRequestBody = (
},
}
: {}),
+ ...(transformDetailsState._meta ? { _meta: transformDetailsState._meta } : {}),
// conditionally add additional settings
...getCreateTransformSettingsRequestBody(transformDetailsState),
});
diff --git a/x-pack/plugins/transform/public/app/hooks/use_index_data.test.tsx b/x-pack/plugins/transform/public/app/hooks/use_index_data.test.tsx
index 9729cc8e62b1f9..7aae41cf2e769c 100644
--- a/x-pack/plugins/transform/public/app/hooks/use_index_data.test.tsx
+++ b/x-pack/plugins/transform/public/app/hooks/use_index_data.test.tsx
@@ -78,7 +78,8 @@ describe('Transform: useIndexData()', () => {
});
});
-describe('Transform: with useIndexData()', () => {
+// FLAKY: https://github.com/elastic/kibana/issues/109943
+describe.skip('Transform: with useIndexData()', () => {
test('Minimal initialization, no cross cluster search warning.', async () => {
// Arrange
const indexPattern = {
diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/common.ts b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/common.ts
index 39b1a2de26f8ec..21e6bce204ec85 100644
--- a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/common.ts
+++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/common.ts
@@ -27,6 +27,7 @@ export interface StepDetailsExposedState {
transformSettingsDocsPerSecond?: number;
valid: boolean;
indexPatternTimeField?: string | undefined;
+ _meta?: Record;
}
const defaultContinuousModeDelay = '60s';
@@ -94,6 +95,10 @@ export function applyTransformConfigToDetailsState(
state.transformSettingsDocsPerSecond = transformConfig.settings.docs_per_second;
}
}
+
+ if (transformConfig._meta) {
+ state._meta = transformConfig._meta;
+ }
}
return state;
}
diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_form.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_form.tsx
index 416bad15d800a6..eda95013f60bd1 100644
--- a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_form.tsx
+++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_details/step_details_form.tsx
@@ -289,6 +289,7 @@ export const StepDetailsForm: FC = React.memo(
touched: true,
valid,
indexPatternTimeField,
+ _meta: defaults._meta,
});
// custom comparison
/* eslint-disable react-hooks/exhaustive-deps */
diff --git a/x-pack/test/accessibility/apps/index_lifecycle_management.ts b/x-pack/test/accessibility/apps/index_lifecycle_management.ts
index 35f4a8e1adea57..6cec8d1cb891ab 100644
--- a/x-pack/test/accessibility/apps/index_lifecycle_management.ts
+++ b/x-pack/test/accessibility/apps/index_lifecycle_management.ts
@@ -7,6 +7,7 @@
import { FtrProviderContext } from '../ftr_provider_context';
+const REPO_NAME = 'test';
const POLICY_NAME = 'ilm-a11y-test';
const POLICY_ALL_PHASES = {
policy: {
@@ -23,7 +24,7 @@ const POLICY_ALL_PHASES = {
frozen: {
actions: {
searchable_snapshot: {
- snapshot_repository: 'test',
+ snapshot_repository: REPO_NAME,
},
},
},
@@ -46,7 +47,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
const esClient = getService('es');
const a11y = getService('a11y');
+ const filterByPolicyName = async (policyName: string) => {
+ await testSubjects.setValue('ilmSearchBar', policyName);
+ };
+
const findPolicyLinkInListView = async (policyName: string) => {
+ await filterByPolicyName(policyName);
const links = await testSubjects.findAll('policyTablePolicyNameLink');
for (const link of links) {
const name = await link.getVisibleText();
@@ -57,11 +63,19 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
throw new Error(`Could not find ${policyName} in policy table`);
};
- // FLAKY
- // https://github.com/elastic/kibana/issues/114541
- // https://github.com/elastic/kibana/issues/114542
- describe.skip('Index Lifecycle Management', async () => {
+ describe('Index Lifecycle Management', async () => {
before(async () => {
+ await esClient.snapshot.createRepository({
+ name: REPO_NAME,
+ body: {
+ type: 'fs',
+ settings: {
+ // use one of the values defined in path.repo in test/functional/config.js
+ location: '/tmp/',
+ },
+ },
+ verify: false,
+ });
await esClient.ilm.putLifecycle({ name: POLICY_NAME, body: POLICY_ALL_PHASES });
await esClient.indices.putIndexTemplate({
name: indexTemplateName,
@@ -79,6 +93,9 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
after(async () => {
+ await esClient.snapshot.deleteRepository({
+ name: REPO_NAME,
+ });
await esClient.ilm.deleteLifecycle({ name: POLICY_NAME });
await esClient.indices.deleteIndexTemplate({ name: indexTemplateName });
});
@@ -144,6 +161,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
it('Add policy to index template modal', async () => {
+ await filterByPolicyName(POLICY_NAME);
const policyRow = await testSubjects.find(`policyTableRow-${POLICY_NAME}`);
const addPolicyButton = await policyRow.findByTestSubject('addPolicyToTemplate');
@@ -157,6 +175,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
it('Delete policy modal', async () => {
+ await filterByPolicyName(POLICY_NAME);
const policyRow = await testSubjects.find(`policyTableRow-${POLICY_NAME}`);
const deleteButton = await policyRow.findByTestSubject('deletePolicy');
@@ -170,6 +189,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
it('Index templates flyout', async () => {
+ await filterByPolicyName(POLICY_NAME);
const policyRow = await testSubjects.find(`policyTableRow-${POLICY_NAME}`);
const actionsButton = await policyRow.findByTestSubject('viewIndexTemplates');
diff --git a/x-pack/test/api_integration/apis/security_solution/authentications.ts b/x-pack/test/api_integration/apis/security_solution/authentications.ts
index 4ea8b8ab82e16f..8254ce034d2a5b 100644
--- a/x-pack/test/api_integration/apis/security_solution/authentications.ts
+++ b/x-pack/test/api_integration/apis/security_solution/authentications.ts
@@ -6,7 +6,10 @@
*/
import expect from '@kbn/expect';
-import { HostsQueries } from '../../../../plugins/security_solution/common/search_strategy';
+import {
+ HostAuthenticationsStrategyResponse,
+ HostsQueries,
+} from '../../../../plugins/security_solution/common/search_strategy';
import { FtrProviderContext } from '../../ftr_provider_context';
@@ -22,16 +25,19 @@ const EDGE_LENGTH = 1;
export default function ({ getService }: FtrProviderContext) {
const esArchiver = getService('esArchiver');
const supertest = getService('supertest');
+ const bsearch = getService('bsearch');
describe('authentications', () => {
- before(() => esArchiver.load('x-pack/test/functional/es_archives/auditbeat/hosts'));
- after(() => esArchiver.unload('x-pack/test/functional/es_archives/auditbeat/hosts'));
+ before(async () => await esArchiver.load('x-pack/test/functional/es_archives/auditbeat/hosts'));
+
+ after(
+ async () => await esArchiver.unload('x-pack/test/functional/es_archives/auditbeat/hosts')
+ );
it('Make sure that we get Authentication data', async () => {
- const { body: authentications } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
+ const authentications = await bsearch.send({
+ supertest,
+ options: {
factoryQueryType: HostsQueries.authentications,
timerange: {
interval: '12h',
@@ -47,9 +53,9 @@ export default function ({ getService }: FtrProviderContext) {
defaultIndex: ['auditbeat-*'],
docValueFields: [],
inspect: false,
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
+ },
+ strategy: 'securitySolutionSearchStrategy',
+ });
expect(authentications.edges.length).to.be(EDGE_LENGTH);
expect(authentications.totalCount).to.be(TOTAL_COUNT);
@@ -57,10 +63,9 @@ export default function ({ getService }: FtrProviderContext) {
});
it('Make sure that pagination is working in Authentications query', async () => {
- const { body: authentications } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
+ const authentications = await bsearch.send({
+ supertest,
+ options: {
factoryQueryType: HostsQueries.authentications,
timerange: {
interval: '12h',
@@ -76,16 +81,16 @@ export default function ({ getService }: FtrProviderContext) {
defaultIndex: ['auditbeat-*'],
docValueFields: [],
inspect: false,
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
+ },
+ strategy: 'securitySolutionSearchStrategy',
+ });
expect(authentications.edges.length).to.be(EDGE_LENGTH);
expect(authentications.totalCount).to.be(TOTAL_COUNT);
- expect(authentications.edges[0]!.node.lastSuccess!.source!.ip).to.eql([
+ expect(authentications.edges[0].node.lastSuccess?.source?.ip).to.eql([
LAST_SUCCESS_SOURCE_IP,
]);
- expect(authentications.edges[0]!.node.lastSuccess!.host!.name).to.eql([HOST_NAME]);
+ expect(authentications.edges[0].node.lastSuccess?.host?.name).to.eql([HOST_NAME]);
});
});
}
diff --git a/x-pack/test/api_integration/apis/security_solution/events.ts b/x-pack/test/api_integration/apis/security_solution/events.ts
index f6a668679b11d2..fef37e9939fcb3 100644
--- a/x-pack/test/api_integration/apis/security_solution/events.ts
+++ b/x-pack/test/api_integration/apis/security_solution/events.ts
@@ -11,13 +11,13 @@ import { JsonObject } from '@kbn/utility-types';
import {
Direction,
TimelineEventsQueries,
+ TimelineEventsAllStrategyResponse,
} from '../../../../plugins/security_solution/common/search_strategy';
import { FtrProviderContext } from '../../ftr_provider_context';
import { getDocValueFields, getFieldsToRequest, getFilterValue } from './utils';
const TO = '3000-01-01T00:00:00.000Z';
const FROM = '2000-01-01T00:00:00.000Z';
-const TEST_URL = '/internal/search/timelineSearchStrategy/';
// typical values that have to change after an update from "scripts/es_archiver"
const DATA_COUNT = 7;
const HOST_NAME = 'suricata-sensor-amsterdam';
@@ -30,6 +30,8 @@ const LIMITED_PAGE_SIZE = 2;
export default function ({ getService }: FtrProviderContext) {
const esArchiver = getService('esArchiver');
const supertest = getService('supertest');
+ const bsearch = getService('bsearch');
+
const getPostBody = (): JsonObject => ({
defaultIndex: ['auditbeat-*'],
docValueFields: getDocValueFields(),
@@ -66,14 +68,14 @@ export default function ({ getService }: FtrProviderContext) {
});
it('returns Timeline data', async () => {
- const resp = await supertest
- .post(TEST_URL)
- .set('kbn-xsrf', 'true')
- .set('Content-Type', 'application/json')
- .send(getPostBody())
- .expect(200);
+ const timeline = await bsearch.send({
+ supertest,
+ options: {
+ ...getPostBody(),
+ },
+ strategy: 'timelineSearchStrategy',
+ });
- const timeline = resp.body;
expect(timeline.edges.length).to.be(EDGE_LENGTH);
expect(timeline.edges[0].node.data.length).to.be(DATA_COUNT);
expect(timeline.totalCount).to.be(TOTAL_COUNT);
@@ -82,20 +84,17 @@ export default function ({ getService }: FtrProviderContext) {
});
it('returns paginated Timeline query', async () => {
- const resp = await supertest
- .post(TEST_URL)
- .set('kbn-xsrf', 'true')
- .set('Content-Type', 'application/json')
- .send({
+ const timeline = await bsearch.send({
+ supertest,
+ options: {
...getPostBody(),
pagination: {
activePage: 0,
querySize: LIMITED_PAGE_SIZE,
},
- })
- .expect(200);
-
- const timeline = resp.body;
+ },
+ strategy: 'timelineSearchStrategy',
+ });
expect(timeline.edges.length).to.be(LIMITED_PAGE_SIZE);
expect(timeline.edges[0].node.data.length).to.be(DATA_COUNT);
expect(timeline.totalCount).to.be(TOTAL_COUNT);
diff --git a/x-pack/test/api_integration/apis/security_solution/host_details.ts b/x-pack/test/api_integration/apis/security_solution/host_details.ts
index 114f60a21c4e35..d2de0f84a37698 100644
--- a/x-pack/test/api_integration/apis/security_solution/host_details.ts
+++ b/x-pack/test/api_integration/apis/security_solution/host_details.ts
@@ -7,16 +7,24 @@
import expect from '@kbn/expect';
import { FtrProviderContext } from '../../ftr_provider_context';
-import { HostsQueries } from '../../../../plugins/security_solution/common/search_strategy';
+import {
+ HostDetailsStrategyResponse,
+ HostsQueries,
+} from '../../../../plugins/security_solution/common/search_strategy';
export default function ({ getService }: FtrProviderContext) {
const esArchiver = getService('esArchiver');
const supertest = getService('supertest');
+ const bsearch = getService('bsearch');
describe('Host Details', () => {
describe('With filebeat', () => {
- before(() => esArchiver.load('x-pack/test/functional/es_archives/filebeat/default'));
- after(() => esArchiver.unload('x-pack/test/functional/es_archives/filebeat/default'));
+ before(
+ async () => await esArchiver.load('x-pack/test/functional/es_archives/filebeat/default')
+ );
+ after(
+ async () => await esArchiver.unload('x-pack/test/functional/es_archives/filebeat/default')
+ );
const FROM = '2000-01-01T00:00:00.000Z';
const TO = '3000-01-01T00:00:00.000Z';
@@ -213,12 +221,9 @@ export default function ({ getService }: FtrProviderContext) {
};
it('Make sure that we get HostDetails data', async () => {
- const {
- body: { hostDetails },
- } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
+ const { hostDetails } = await bsearch.send({
+ supertest,
+ options: {
factoryQueryType: HostsQueries.details,
timerange: {
interval: '12h',
@@ -229,9 +234,9 @@ export default function ({ getService }: FtrProviderContext) {
docValueFields: [],
hostName: 'raspberrypi',
inspect: false,
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
+ },
+ strategy: 'securitySolutionSearchStrategy',
+ });
expect(hostDetails).to.eql(expectedResult.hostDetails);
});
});
diff --git a/x-pack/test/api_integration/apis/security_solution/hosts.ts b/x-pack/test/api_integration/apis/security_solution/hosts.ts
index 4df46002e9a13f..bb2969f85a98b8 100644
--- a/x-pack/test/api_integration/apis/security_solution/hosts.ts
+++ b/x-pack/test/api_integration/apis/security_solution/hosts.ts
@@ -10,6 +10,9 @@ import {
HostsQueries,
Direction,
HostsFields,
+ HostsStrategyResponse,
+ HostDetailsStrategyResponse,
+ HostFirstLastSeenStrategyResponse,
} from '../../../../plugins/security_solution/common/search_strategy';
import { FtrProviderContext } from '../../ftr_provider_context';
@@ -26,17 +29,19 @@ const CURSOR_ID = '2ab45fc1c41e4c84bbd02202a7e5761f';
export default function ({ getService }: FtrProviderContext) {
const esArchiver = getService('esArchiver');
const supertest = getService('supertest');
+ const bsearch = getService('bsearch');
- // Failing: See https://github.com/elastic/kibana/issues/104260
- describe.skip('hosts', () => {
- before(() => esArchiver.load('x-pack/test/functional/es_archives/auditbeat/hosts'));
- after(() => esArchiver.unload('x-pack/test/functional/es_archives/auditbeat/hosts'));
+ describe('hosts', () => {
+ before(async () => await esArchiver.load('x-pack/test/functional/es_archives/auditbeat/hosts'));
+
+ after(
+ async () => await esArchiver.unload('x-pack/test/functional/es_archives/auditbeat/hosts')
+ );
it('Make sure that we get Hosts Table data', async () => {
- const { body: hosts } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
+ const hosts = await bsearch.send({
+ supertest,
+ options: {
factoryQueryType: HostsQueries.hosts,
timerange: {
interval: '12h',
@@ -56,19 +61,18 @@ export default function ({ getService }: FtrProviderContext) {
querySize: 1,
},
inspect: false,
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
+ },
+ strategy: 'securitySolutionSearchStrategy',
+ });
expect(hosts.edges.length).to.be(EDGE_LENGTH);
expect(hosts.totalCount).to.be(TOTAL_COUNT);
expect(hosts.pageInfo.fakeTotalCount).to.equal(3);
});
it('Make sure that pagination is working in Hosts Table query', async () => {
- const { body: hosts } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
+ const hosts = await bsearch.send({
+ supertest,
+ options: {
factoryQueryType: HostsQueries.hosts,
timerange: {
interval: '12h',
@@ -88,16 +92,32 @@ export default function ({ getService }: FtrProviderContext) {
querySize: 2,
},
inspect: false,
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
+ },
+ strategy: 'securitySolutionSearchStrategy',
+ });
expect(hosts.edges.length).to.be(EDGE_LENGTH);
expect(hosts.totalCount).to.be(TOTAL_COUNT);
- expect(hosts.edges[0]!.node.host!.os!.name).to.eql([HOST_NAME]);
+ expect(hosts.edges[0].node.host?.os?.name).to.eql([HOST_NAME]);
});
it('Make sure that we get Host details data', async () => {
- const expectedHostDetails = {
+ const { hostDetails } = await bsearch.send({
+ supertest,
+ options: {
+ factoryQueryType: HostsQueries.details,
+ hostName: 'zeek-sensor-san-francisco',
+ timerange: {
+ interval: '12h',
+ to: TO,
+ from: FROM,
+ },
+ defaultIndex: ['auditbeat-*'],
+ docValueFields: [],
+ inspect: false,
+ },
+ strategy: 'securitySolutionSearchStrategy',
+ });
+ expect(hostDetails).to.eql({
_id: 'zeek-sensor-san-francisco',
host: {
architecture: ['x86_64'],
@@ -122,91 +142,66 @@ export default function ({ getService }: FtrProviderContext) {
provider: ['digitalocean'],
region: ['sfo2'],
},
- };
- const {
- body: { hostDetails },
- } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
- factoryQueryType: HostsQueries.details,
- hostName: 'zeek-sensor-san-francisco',
- timerange: {
- interval: '12h',
- to: TO,
- from: FROM,
- },
- defaultIndex: ['auditbeat-*'],
- docValueFields: [],
- inspect: false,
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
-
- expect(hostDetails).to.eql(expectedHostDetails);
+ });
});
it('Make sure that we get First Seen for a Host without docValueFields', async () => {
- const { body: firstLastSeenHost } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
+ const firstLastSeenHost = await bsearch.send({
+ supertest,
+ options: {
factoryQueryType: HostsQueries.firstOrLastSeen,
defaultIndex: ['auditbeat-*'],
docValueFields: [],
hostName: 'zeek-sensor-san-francisco',
order: 'asc',
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
+ },
+ strategy: 'securitySolutionSearchStrategy',
+ });
expect(firstLastSeenHost.firstSeen).to.eql('2019-02-19T19:36:23.561Z');
});
it('Make sure that we get Last Seen for a Host without docValueFields', async () => {
- const { body: firstLastSeenHost } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
+ const firstLastSeenHost = await bsearch.send({
+ supertest,
+ options: {
factoryQueryType: HostsQueries.firstOrLastSeen,
defaultIndex: ['auditbeat-*'],
docValueFields: [],
hostName: 'zeek-sensor-san-francisco',
order: 'desc',
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
+ },
+ strategy: 'securitySolutionSearchStrategy',
+ });
expect(firstLastSeenHost.lastSeen).to.eql('2019-02-19T20:42:33.561Z');
});
it('Make sure that we get First Seen for a Host with docValueFields', async () => {
- const { body: firstLastSeenHost } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
+ const firstLastSeenHost = await bsearch.send({
+ supertest,
+ options: {
factoryQueryType: HostsQueries.firstOrLastSeen,
defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'],
docValueFields: [{ field: '@timestamp', format: 'epoch_millis' }],
hostName: 'zeek-sensor-san-francisco',
order: 'asc',
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
+ },
+ strategy: 'securitySolutionSearchStrategy',
+ });
expect(firstLastSeenHost.firstSeen).to.eql(new Date('2019-02-19T19:36:23.561Z').valueOf());
});
it('Make sure that we get Last Seen for a Host with docValueFields', async () => {
- const { body: firstLastSeenHost } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
+ const firstLastSeenHost = await bsearch.send({
+ supertest,
+ options: {
factoryQueryType: HostsQueries.firstOrLastSeen,
defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'],
docValueFields: [{ field: '@timestamp', format: 'epoch_millis' }],
hostName: 'zeek-sensor-san-francisco',
order: 'desc',
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
+ },
+ strategy: 'securitySolutionSearchStrategy',
+ });
expect(firstLastSeenHost.lastSeen).to.eql(new Date('2019-02-19T20:42:33.561Z').valueOf());
});
});
diff --git a/x-pack/test/api_integration/apis/security_solution/kpi_hosts.ts b/x-pack/test/api_integration/apis/security_solution/kpi_hosts.ts
index 632f738d85f362..f38cf406a9dbe5 100644
--- a/x-pack/test/api_integration/apis/security_solution/kpi_hosts.ts
+++ b/x-pack/test/api_integration/apis/security_solution/kpi_hosts.ts
@@ -6,18 +6,27 @@
*/
import expect from '@kbn/expect';
-import { HostsKpiQueries } from '../../../../plugins/security_solution/common/search_strategy';
+import {
+ HostsKpiAuthenticationsStrategyResponse,
+ HostsKpiHostsStrategyResponse,
+ HostsKpiQueries,
+ HostsKpiUniqueIpsStrategyResponse,
+} from '../../../../plugins/security_solution/common/search_strategy';
import { FtrProviderContext } from '../../ftr_provider_context';
export default function ({ getService }: FtrProviderContext) {
- const retry = getService('retry');
const esArchiver = getService('esArchiver');
const supertest = getService('supertest');
+ const bsearch = getService('bsearch');
describe('Kpi Hosts', () => {
describe('With filebeat', () => {
- before(() => esArchiver.load('x-pack/test/functional/es_archives/filebeat/kpi_hosts'));
- after(() => esArchiver.unload('x-pack/test/functional/es_archives/filebeat/kpi_hosts'));
+ before(
+ async () => await esArchiver.load('x-pack/test/functional/es_archives/filebeat/kpi_hosts')
+ );
+ after(
+ async () => await esArchiver.unload('x-pack/test/functional/es_archives/filebeat/kpi_hosts')
+ );
const FROM = '2000-01-01T00:00:00.000Z';
const TO = '3000-01-01T00:00:00.000Z';
@@ -50,88 +59,80 @@ export default function ({ getService }: FtrProviderContext) {
};
it('Make sure that we get KpiHosts data', async () => {
- await retry.try(async () => {
- const { body: kpiHosts } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
- factoryQueryType: HostsKpiQueries.kpiHosts,
- timerange: {
- interval: '12h',
- to: TO,
- from: FROM,
- },
- defaultIndex: ['filebeat-*'],
- docValueFields: [],
- inspect: false,
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
-
- expect(kpiHosts.hostsHistogram!).to.eql(expectedResult.hostsHistogram);
- expect(kpiHosts.hosts!).to.eql(expectedResult.hosts);
+ const kpiHosts = await bsearch.send({
+ supertest,
+ options: {
+ factoryQueryType: HostsKpiQueries.kpiHosts,
+ timerange: {
+ interval: '12h',
+ to: TO,
+ from: FROM,
+ },
+ defaultIndex: ['filebeat-*'],
+ docValueFields: [],
+ inspect: false,
+ },
+ strategy: 'securitySolutionSearchStrategy',
});
+ expect(kpiHosts.hostsHistogram).to.eql(expectedResult.hostsHistogram);
+ expect(kpiHosts.hosts).to.eql(expectedResult.hosts);
});
it('Make sure that we get KpiAuthentications data', async () => {
- await retry.try(async () => {
- const { body } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
- factoryQueryType: HostsKpiQueries.kpiAuthentications,
- timerange: {
- interval: '12h',
- to: TO,
- from: FROM,
- },
- defaultIndex: ['filebeat-*'],
- docValueFields: [],
- inspect: false,
- /* We need a very long timeout to avoid returning just partial data.
- ** https://github.com/elastic/kibana/blob/master/x-pack/test/api_integration/apis/search/search.ts#L18
- */
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
- expect(body.authenticationsSuccess!).to.eql(expectedResult.authSuccess);
- expect(body.authenticationsSuccessHistogram!).to.eql(expectedResult.authSuccessHistogram);
- expect(body.authenticationsFailure!).to.eql(expectedResult.authFailure);
- expect(body.authenticationsFailureHistogram!).to.eql(expectedResult.authFailureHistogram);
+ const body = await bsearch.send({
+ supertest,
+ options: {
+ factoryQueryType: HostsKpiQueries.kpiAuthentications,
+ timerange: {
+ interval: '12h',
+ to: TO,
+ from: FROM,
+ },
+ defaultIndex: ['filebeat-*'],
+ docValueFields: [],
+ inspect: false,
+ },
+ strategy: 'securitySolutionSearchStrategy',
});
+ expect(body.authenticationsSuccess).to.eql(expectedResult.authSuccess);
+ expect(body.authenticationsSuccessHistogram).to.eql(expectedResult.authSuccessHistogram);
+ expect(body.authenticationsFailure).to.eql(expectedResult.authFailure);
+ expect(body.authenticationsFailureHistogram).to.eql(expectedResult.authFailureHistogram);
});
it('Make sure that we get KpiUniqueIps data', async () => {
- await retry.try(async () => {
- const { body } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
- factoryQueryType: HostsKpiQueries.kpiUniqueIps,
- timerange: {
- interval: '12h',
- to: TO,
- from: FROM,
- },
- defaultIndex: ['filebeat-*'],
- docValueFields: [],
- inspect: false,
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
- expect(body.uniqueDestinationIps!).to.eql(expectedResult.uniqueDestinationIps);
- expect(body.uniqueDestinationIpsHistogram!).to.eql(
- expectedResult.uniqueDestinationIpsHistogram
- );
- expect(body.uniqueSourceIps!).to.eql(expectedResult.uniqueSourceIps);
- expect(body.uniqueSourceIpsHistogram!).to.eql(expectedResult.uniqueSourceIpsHistogram);
+ const body = await bsearch.send({
+ supertest,
+ options: {
+ factoryQueryType: HostsKpiQueries.kpiUniqueIps,
+ timerange: {
+ interval: '12h',
+ to: TO,
+ from: FROM,
+ },
+ defaultIndex: ['filebeat-*'],
+ docValueFields: [],
+ inspect: false,
+ },
+ strategy: 'securitySolutionSearchStrategy',
});
+ expect(body.uniqueDestinationIps).to.eql(expectedResult.uniqueDestinationIps);
+ expect(body.uniqueDestinationIpsHistogram).to.eql(
+ expectedResult.uniqueDestinationIpsHistogram
+ );
+ expect(body.uniqueSourceIps).to.eql(expectedResult.uniqueSourceIps);
+ expect(body.uniqueSourceIpsHistogram).to.eql(expectedResult.uniqueSourceIpsHistogram);
});
});
describe('With auditbeat', () => {
- before(() => esArchiver.load('x-pack/test/functional/es_archives/auditbeat/kpi_hosts'));
- after(() => esArchiver.unload('x-pack/test/functional/es_archives/auditbeat/kpi_hosts'));
+ before(
+ async () => await esArchiver.load('x-pack/test/functional/es_archives/auditbeat/kpi_hosts')
+ );
+ after(
+ async () =>
+ await esArchiver.unload('x-pack/test/functional/es_archives/auditbeat/kpi_hosts')
+ );
const FROM = '2000-01-01T00:00:00.000Z';
const TO = '3000-01-01T00:00:00.000Z';
@@ -188,79 +189,69 @@ export default function ({ getService }: FtrProviderContext) {
};
it('Make sure that we get KpiHosts data', async () => {
- await retry.try(async () => {
- const { body: kpiHosts } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
- factoryQueryType: HostsKpiQueries.kpiHosts,
- timerange: {
- interval: '12h',
- to: TO,
- from: FROM,
- },
- defaultIndex: ['auditbeat-*'],
- docValueFields: [],
- inspect: false,
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
-
- expect(kpiHosts.hostsHistogram!).to.eql(expectedResult.hostsHistogram);
- expect(kpiHosts.hosts!).to.eql(expectedResult.hosts);
+ const kpiHosts = await bsearch.send({
+ supertest,
+ options: {
+ factoryQueryType: HostsKpiQueries.kpiHosts,
+ timerange: {
+ interval: '12h',
+ to: TO,
+ from: FROM,
+ },
+ defaultIndex: ['auditbeat-*'],
+ docValueFields: [],
+ inspect: false,
+ },
+ strategy: 'securitySolutionSearchStrategy',
});
+ expect(kpiHosts.hostsHistogram).to.eql(expectedResult.hostsHistogram);
+ expect(kpiHosts.hosts).to.eql(expectedResult.hosts);
});
it('Make sure that we get KpiAuthentications data', async () => {
- await retry.try(async () => {
- const { body } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
- factoryQueryType: HostsKpiQueries.kpiAuthentications,
- timerange: {
- interval: '12h',
- to: TO,
- from: FROM,
- },
- defaultIndex: ['auditbeat-*'],
- docValueFields: [],
- inspect: false,
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
- expect(body.authenticationsSuccess!).to.eql(expectedResult.authSuccess);
- expect(body.authenticationsSuccessHistogram!).to.eql(expectedResult.authSuccessHistogram);
- expect(body.authenticationsFailure!).to.eql(expectedResult.authFailure);
- expect(body.authenticationsFailureHistogram!).to.eql(expectedResult.authFailureHistogram);
+ const body = await bsearch.send({
+ supertest,
+ options: {
+ factoryQueryType: HostsKpiQueries.kpiAuthentications,
+ timerange: {
+ interval: '12h',
+ to: TO,
+ from: FROM,
+ },
+ defaultIndex: ['auditbeat-*'],
+ docValueFields: [],
+ inspect: false,
+ },
+ strategy: 'securitySolutionSearchStrategy',
});
+ expect(body.authenticationsSuccess).to.eql(expectedResult.authSuccess);
+ expect(body.authenticationsSuccessHistogram).to.eql(expectedResult.authSuccessHistogram);
+ expect(body.authenticationsFailure).to.eql(expectedResult.authFailure);
+ expect(body.authenticationsFailureHistogram).to.eql(expectedResult.authFailureHistogram);
});
it('Make sure that we get KpiUniqueIps data', async () => {
- await retry.try(async () => {
- const { body } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
- factoryQueryType: HostsKpiQueries.kpiUniqueIps,
- timerange: {
- interval: '12h',
- to: TO,
- from: FROM,
- },
- defaultIndex: ['auditbeat-*'],
- docValueFields: [],
- inspect: false,
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
- expect(body.uniqueDestinationIps!).to.eql(expectedResult.uniqueDestinationIps);
- expect(body.uniqueDestinationIpsHistogram!).to.eql(
- expectedResult.uniqueDestinationIpsHistogram
- );
- expect(body.uniqueSourceIps!).to.eql(expectedResult.uniqueSourceIps);
- expect(body.uniqueSourceIpsHistogram!).to.eql(expectedResult.uniqueSourceIpsHistogram);
+ const body = await bsearch.send({
+ supertest,
+ options: {
+ factoryQueryType: HostsKpiQueries.kpiUniqueIps,
+ timerange: {
+ interval: '12h',
+ to: TO,
+ from: FROM,
+ },
+ defaultIndex: ['auditbeat-*'],
+ docValueFields: [],
+ inspect: false,
+ },
+ strategy: 'securitySolutionSearchStrategy',
});
+ expect(body.uniqueDestinationIps!).to.eql(expectedResult.uniqueDestinationIps);
+ expect(body.uniqueDestinationIpsHistogram!).to.eql(
+ expectedResult.uniqueDestinationIpsHistogram
+ );
+ expect(body.uniqueSourceIps!).to.eql(expectedResult.uniqueSourceIps);
+ expect(body.uniqueSourceIpsHistogram!).to.eql(expectedResult.uniqueSourceIpsHistogram);
});
});
});
diff --git a/x-pack/test/api_integration/apis/security_solution/kpi_network.ts b/x-pack/test/api_integration/apis/security_solution/kpi_network.ts
index 53b099bbe18d39..637b69ff1daaae 100644
--- a/x-pack/test/api_integration/apis/security_solution/kpi_network.ts
+++ b/x-pack/test/api_integration/apis/security_solution/kpi_network.ts
@@ -7,16 +7,28 @@
import expect from '@kbn/expect';
import { FtrProviderContext } from '../../ftr_provider_context';
-import { NetworkKpiQueries } from '../../../../plugins/security_solution/common/search_strategy';
+import {
+ NetworkKpiDnsStrategyResponse,
+ NetworkKpiNetworkEventsStrategyResponse,
+ NetworkKpiQueries,
+ NetworkKpiTlsHandshakesStrategyResponse,
+ NetworkKpiUniqueFlowsStrategyResponse,
+ NetworkKpiUniquePrivateIpsStrategyResponse,
+} from '../../../../plugins/security_solution/common/search_strategy';
export default function ({ getService }: FtrProviderContext) {
const esArchiver = getService('esArchiver');
const supertest = getService('supertest');
+ const bsearch = getService('bsearch');
describe('Kpi Network', () => {
describe('With filebeat', () => {
- before(() => esArchiver.load('x-pack/test/functional/es_archives/filebeat/default'));
- after(() => esArchiver.unload('x-pack/test/functional/es_archives/filebeat/default'));
+ before(
+ async () => await esArchiver.load('x-pack/test/functional/es_archives/filebeat/default')
+ );
+ after(
+ async () => await esArchiver.unload('x-pack/test/functional/es_archives/filebeat/default')
+ );
const FROM = '2000-01-01T00:00:00.000Z';
const TO = '3000-01-01T00:00:00.000Z';
@@ -66,10 +78,9 @@ export default function ({ getService }: FtrProviderContext) {
};
it('Make sure that we get KpiNetwork uniqueFlows data', async () => {
- const { body: kpiNetwork } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
+ const kpiNetwork = await bsearch.send({
+ supertest,
+ options: {
factoryQueryType: NetworkKpiQueries.uniqueFlows,
timerange: {
interval: '12h',
@@ -79,18 +90,16 @@ export default function ({ getService }: FtrProviderContext) {
defaultIndex: ['filebeat-*'],
docValueFields: [],
inspect: false,
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
-
+ },
+ strategy: 'securitySolutionSearchStrategy',
+ });
expect(kpiNetwork.uniqueFlowId).to.eql(expectedResult.uniqueFlowId);
});
it('Make sure that we get KpiNetwork networkEvents data', async () => {
- const { body: kpiNetwork } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
+ const kpiNetwork = await bsearch.send({
+ supertest,
+ options: {
factoryQueryType: NetworkKpiQueries.networkEvents,
timerange: {
interval: '12h',
@@ -100,18 +109,16 @@ export default function ({ getService }: FtrProviderContext) {
defaultIndex: ['filebeat-*'],
docValueFields: [],
inspect: false,
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
-
+ },
+ strategy: 'securitySolutionSearchStrategy',
+ });
expect(kpiNetwork.networkEvents).to.eql(expectedResult.networkEvents);
});
it('Make sure that we get KpiNetwork DNS data', async () => {
- const { body: kpiNetwork } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
+ const kpiNetwork = await bsearch.send({
+ supertest,
+ options: {
factoryQueryType: NetworkKpiQueries.dns,
timerange: {
interval: '12h',
@@ -121,18 +128,16 @@ export default function ({ getService }: FtrProviderContext) {
defaultIndex: ['filebeat-*'],
docValueFields: [],
inspect: false,
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
-
+ },
+ strategy: 'securitySolutionSearchStrategy',
+ });
expect(kpiNetwork.dnsQueries).to.eql(expectedResult.dnsQueries);
});
it('Make sure that we get KpiNetwork networkEvents data', async () => {
- const { body: kpiNetwork } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
+ const kpiNetwork = await bsearch.send({
+ supertest,
+ options: {
factoryQueryType: NetworkKpiQueries.networkEvents,
timerange: {
interval: '12h',
@@ -142,18 +147,16 @@ export default function ({ getService }: FtrProviderContext) {
defaultIndex: ['filebeat-*'],
docValueFields: [],
inspect: false,
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
-
+ },
+ strategy: 'securitySolutionSearchStrategy',
+ });
expect(kpiNetwork.networkEvents).to.eql(expectedResult.networkEvents);
});
it('Make sure that we get KpiNetwork tlsHandshakes data', async () => {
- const { body: kpiNetwork } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
+ const kpiNetwork = await bsearch.send({
+ supertest,
+ options: {
factoryQueryType: NetworkKpiQueries.tlsHandshakes,
timerange: {
interval: '12h',
@@ -163,18 +166,17 @@ export default function ({ getService }: FtrProviderContext) {
defaultIndex: ['filebeat-*'],
docValueFields: [],
inspect: false,
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
+ },
+ strategy: 'securitySolutionSearchStrategy',
+ });
expect(kpiNetwork.tlsHandshakes).to.eql(expectedResult.tlsHandshakes);
});
it('Make sure that we get KpiNetwork uniquePrivateIps data', async () => {
- const { body: kpiNetwork } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
+ const kpiNetwork = await bsearch.send({
+ supertest,
+ options: {
factoryQueryType: NetworkKpiQueries.uniquePrivateIps,
timerange: {
interval: '12h',
@@ -184,9 +186,9 @@ export default function ({ getService }: FtrProviderContext) {
defaultIndex: ['filebeat-*'],
docValueFields: [],
inspect: false,
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
+ },
+ strategy: 'securitySolutionSearchStrategy',
+ });
expect(kpiNetwork.uniqueDestinationPrivateIps).to.eql(
expectedResult.uniqueDestinationPrivateIps
@@ -202,8 +204,12 @@ export default function ({ getService }: FtrProviderContext) {
});
describe('With packetbeat', () => {
- before(() => esArchiver.load('x-pack/test/functional/es_archives/packetbeat/default'));
- after(() => esArchiver.unload('x-pack/test/functional/es_archives/packetbeat/default'));
+ before(
+ async () => await esArchiver.load('x-pack/test/functional/es_archives/packetbeat/default')
+ );
+ after(
+ async () => await esArchiver.unload('x-pack/test/functional/es_archives/packetbeat/default')
+ );
const FROM = '2000-01-01T00:00:00.000Z';
const TO = '3000-01-01T00:00:00.000Z';
@@ -219,10 +225,9 @@ export default function ({ getService }: FtrProviderContext) {
};
it('Make sure that we get KpiNetwork uniqueFlows data', async () => {
- const { body: kpiNetwork } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
+ const kpiNetwork = await bsearch.send({
+ supertest,
+ options: {
factoryQueryType: NetworkKpiQueries.uniqueFlows,
timerange: {
interval: '12h',
@@ -232,18 +237,16 @@ export default function ({ getService }: FtrProviderContext) {
defaultIndex: ['packetbeat-*'],
docValueFields: [],
inspect: false,
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
-
+ },
+ strategy: 'securitySolutionSearchStrategy',
+ });
expect(kpiNetwork.uniqueFlowId).to.eql(expectedResult.uniqueFlowId);
});
it('Make sure that we get KpiNetwork DNS data', async () => {
- const { body: kpiNetwork } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
+ const kpiNetwork = await bsearch.send({
+ supertest,
+ options: {
factoryQueryType: NetworkKpiQueries.dns,
timerange: {
interval: '12h',
@@ -253,18 +256,16 @@ export default function ({ getService }: FtrProviderContext) {
defaultIndex: ['packetbeat-*'],
docValueFields: [],
inspect: false,
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
-
+ },
+ strategy: 'securitySolutionSearchStrategy',
+ });
expect(kpiNetwork.dnsQueries).to.eql(expectedResult.dnsQueries);
});
it('Make sure that we get KpiNetwork networkEvents data', async () => {
- const { body: kpiNetwork } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
+ const kpiNetwork = await bsearch.send({
+ supertest,
+ options: {
factoryQueryType: NetworkKpiQueries.networkEvents,
timerange: {
interval: '12h',
@@ -274,18 +275,17 @@ export default function ({ getService }: FtrProviderContext) {
defaultIndex: ['packetbeat-*'],
docValueFields: [],
inspect: false,
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
+ },
+ strategy: 'securitySolutionSearchStrategy',
+ });
expect(kpiNetwork.networkEvents).to.eql(expectedResult.networkEvents);
});
it('Make sure that we get KpiNetwork tlsHandshakes data', async () => {
- const { body: kpiNetwork } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
+ const kpiNetwork = await bsearch.send({
+ supertest,
+ options: {
factoryQueryType: NetworkKpiQueries.tlsHandshakes,
timerange: {
interval: '12h',
@@ -295,18 +295,16 @@ export default function ({ getService }: FtrProviderContext) {
defaultIndex: ['packetbeat-*'],
docValueFields: [],
inspect: false,
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
-
+ },
+ strategy: 'securitySolutionSearchStrategy',
+ });
expect(kpiNetwork.tlsHandshakes).to.eql(expectedResult.tlsHandshakes);
});
it('Make sure that we get KpiNetwork uniquePrivateIps data', async () => {
- const { body: kpiNetwork } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
+ const kpiNetwork = await bsearch.send({
+ supertest,
+ options: {
factoryQueryType: NetworkKpiQueries.uniquePrivateIps,
timerange: {
interval: '12h',
@@ -316,9 +314,9 @@ export default function ({ getService }: FtrProviderContext) {
defaultIndex: ['packetbeat-*'],
docValueFields: [],
inspect: false,
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
+ },
+ strategy: 'securitySolutionSearchStrategy',
+ });
expect(kpiNetwork.uniqueDestinationPrivateIps).to.eql(
expectedResult.uniqueDestinationPrivateIps
diff --git a/x-pack/test/api_integration/apis/security_solution/matrix_dns_histogram.ts b/x-pack/test/api_integration/apis/security_solution/matrix_dns_histogram.ts
index 6040ecd1001d94..c7b6bbb84436fd 100644
--- a/x-pack/test/api_integration/apis/security_solution/matrix_dns_histogram.ts
+++ b/x-pack/test/api_integration/apis/security_solution/matrix_dns_histogram.ts
@@ -6,54 +6,43 @@
*/
import expect from '@kbn/expect';
-import request from 'superagent';
import {
MatrixHistogramQuery,
MatrixHistogramType,
+ NetworkDnsStrategyResponse,
} from '../../../../plugins/security_solution/common/search_strategy';
import { FtrProviderContext } from '../../ftr_provider_context';
-/**
- * Function copied from here:
- * test/api_integration/apis/search/bsearch.ts
- *
- * Splits the JSON lines from bsearch
- */
-export const parseBfetchResponse = (resp: request.Response): Array> => {
- return resp.text
- .trim()
- .split('\n')
- .map((item) => JSON.parse(item));
-};
-
export default function ({ getService }: FtrProviderContext) {
const esArchiver = getService('esArchiver');
const supertest = getService('supertest');
- const retry = getService('retry');
+ const bsearch = getService('bsearch');
describe('Matrix DNS Histogram', () => {
describe('Large data set', () => {
- before(() =>
- esArchiver.load(
- 'x-pack/test/functional/es_archives/security_solution/matrix_dns_histogram/large_dns_query'
- )
+ before(
+ async () =>
+ await esArchiver.load(
+ 'x-pack/test/functional/es_archives/security_solution/matrix_dns_histogram/large_dns_query'
+ )
);
- after(() =>
- esArchiver.unload(
- 'x-pack/test/functional/es_archives/security_solution/matrix_dns_histogram/large_dns_query'
- )
+
+ after(
+ async () =>
+ await esArchiver.unload(
+ 'x-pack/test/functional/es_archives/security_solution/matrix_dns_histogram/large_dns_query'
+ )
);
const FROM = '2000-01-01T00:00:00.000Z';
const TO = '3000-01-01T00:00:00.000Z';
it('Make sure that we get dns data without getting bucket errors when querying large volume of data', async () => {
- const { body: networkDns } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
+ const networkDns = await bsearch.send({
+ supertest,
+ options: {
defaultIndex: ['large_volume_dns_data'],
docValueFields: [],
factoryQueryType: MatrixHistogramQuery,
@@ -62,56 +51,14 @@ export default function ({ getService }: FtrProviderContext) {
'{"bool":{"must":[],"filter":[{"match_all":{}}],"should":[],"must_not":[]}}',
isPtrIncluded: false,
timerange: {
- interval: '12h',
+ interval: '12',
to: TO,
from: FROM,
},
- })
- .expect(200);
-
- if (networkDns.isRunning === true) {
- await retry.waitForWithTimeout('bsearch to give us results', 5000, async () => {
- const resp = await supertest
- .post('/internal/bsearch')
- .set('kbn-xsrf', 'true')
- .send({
- batch: [
- {
- request: {
- id: networkDns.id,
- defaultIndex: ['large_volume_dns_data'],
- docValueFields: [],
- factoryQueryType: MatrixHistogramQuery,
- histogramType: MatrixHistogramType.dns,
- filterQuery:
- '{"bool":{"must":[],"filter":[{"match_all":{}}],"should":[],"must_not":[]}}',
- isPtrIncluded: false,
- timerange: {
- interval: '12h',
- to: TO,
- from: FROM,
- },
- },
- options: {
- strategy: 'securitySolutionSearchStrategy',
- },
- },
- ],
- });
- const parsedResponse = parseBfetchResponse(resp);
- // NOTE: I would like this test to be ".to.equal(6604)" but that is flakey as sometimes the query
- // does not give me that exact value. It gives me failures as seen here with notes: https://github.com/elastic/kibana/issues/97365
- // I don't think this is a bug with the query but possibly a consistency view issue with interacting with the archive
- // so we instead loosen this test up a bit to avoid flake.
- expect(parsedResponse[0].result.rawResponse.aggregations.dns_count.value).to.be.above(
- 0
- );
- return true;
- });
- } else {
- expect(networkDns.isRunning).to.equal(false);
- expect(networkDns.rawResponse.aggregations.dns_count.value).to.equal(6604);
- }
+ },
+ strategy: 'securitySolutionSearchStrategy',
+ });
+ expect(networkDns.rawResponse.aggregations?.dns_count).to.eql({ value: 6604 });
});
});
});
diff --git a/x-pack/test/api_integration/apis/security_solution/network_details.ts b/x-pack/test/api_integration/apis/security_solution/network_details.ts
index 0397e7550c9352..07e526c7c4bf5d 100644
--- a/x-pack/test/api_integration/apis/security_solution/network_details.ts
+++ b/x-pack/test/api_integration/apis/security_solution/network_details.ts
@@ -6,59 +6,70 @@
*/
import expect from '@kbn/expect';
-import { NetworkQueries } from '../../../../plugins/security_solution/common/search_strategy';
+import {
+ NetworkDetailsStrategyResponse,
+ NetworkQueries,
+} from '../../../../plugins/security_solution/common/search_strategy';
import { FtrProviderContext } from '../../ftr_provider_context';
export default function ({ getService }: FtrProviderContext) {
const esArchiver = getService('esArchiver');
const supertest = getService('supertest');
+ const bsearch = getService('bsearch');
+
describe('Network details', () => {
describe('With filebeat', () => {
- before(() => esArchiver.load('x-pack/test/functional/es_archives/filebeat/default'));
- after(() => esArchiver.unload('x-pack/test/functional/es_archives/filebeat/default'));
+ before(
+ async () => await esArchiver.load('x-pack/test/functional/es_archives/filebeat/default')
+ );
+ after(
+ async () => await esArchiver.unload('x-pack/test/functional/es_archives/filebeat/default')
+ );
it('Make sure that we get Network details data', async () => {
- const { body } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
+ const body = await bsearch.send({
+ supertest,
+ options: {
ip: '151.205.0.17',
defaultIndex: ['filebeat-*'],
factoryQueryType: NetworkQueries.details,
docValueFields: [],
inspect: false,
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
+ },
+ strategy: 'securitySolutionSearchStrategy',
+ });
- expect(body.networkDetails!.source!.geo!.continent_name).to.be('North America');
- expect(body.networkDetails!.source!.geo!.location!.lat!).to.be(37.751);
- expect(body.networkDetails!.host.os!.platform!).to.eql(['raspbian']);
+ expect(body.networkDetails.source?.geo.continent_name).to.be('North America');
+ expect(body.networkDetails.source?.geo.location?.lat!).to.be(37.751);
+ expect(body.networkDetails.host?.os?.platform).to.eql(['raspbian']);
});
});
describe('With packetbeat', () => {
- before(() => esArchiver.load('x-pack/test/functional/es_archives/packetbeat/default'));
- after(() => esArchiver.unload('x-pack/test/functional/es_archives/packetbeat/default'));
+ before(
+ async () => await esArchiver.load('x-pack/test/functional/es_archives/packetbeat/default')
+ );
+ after(
+ async () => await esArchiver.unload('x-pack/test/functional/es_archives/packetbeat/default')
+ );
it('Make sure that we get Network details data', async () => {
- const { body } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
+ const body = await bsearch.send({
+ supertest,
+ options: {
ip: '185.53.91.88',
defaultIndex: ['packetbeat-*'],
factoryQueryType: NetworkQueries.details,
docValueFields: [],
inspect: false,
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
+ },
+ strategy: 'securitySolutionSearchStrategy',
+ });
- expect(body.networkDetails!.host.id!).to.eql(['2ce8b1e7d69e4a1d9c6bcddc473da9d9']);
- expect(body.networkDetails!.host.name!).to.eql(['zeek-sensor-amsterdam']);
- expect(body.networkDetails!.host.os!.platform!).to.eql(['ubuntu']);
+ expect(body.networkDetails.host?.id).to.eql(['2ce8b1e7d69e4a1d9c6bcddc473da9d9']);
+ expect(body.networkDetails.host?.name).to.eql(['zeek-sensor-amsterdam']);
+ expect(body.networkDetails.host?.os?.platform!).to.eql(['ubuntu']);
});
});
});
diff --git a/x-pack/test/api_integration/apis/security_solution/network_dns.ts b/x-pack/test/api_integration/apis/security_solution/network_dns.ts
index 80660860a164bc..474c6261babf02 100644
--- a/x-pack/test/api_integration/apis/security_solution/network_dns.ts
+++ b/x-pack/test/api_integration/apis/security_solution/network_dns.ts
@@ -11,6 +11,7 @@ import {
NetworkDnsEdges,
Direction,
NetworkDnsFields,
+ NetworkDnsStrategyResponse,
} from '../../../../plugins/security_solution/common/search_strategy';
import { FtrProviderContext } from '../../ftr_provider_context';
@@ -18,20 +19,24 @@ import { FtrProviderContext } from '../../ftr_provider_context';
export default function ({ getService }: FtrProviderContext) {
const esArchiver = getService('esArchiver');
const supertest = getService('supertest');
+ const bsearch = getService('bsearch');
describe('Network DNS', () => {
describe('With packetbeat', () => {
- before(() => esArchiver.load('x-pack/test/functional/es_archives/packetbeat/dns'));
- after(() => esArchiver.unload('x-pack/test/functional/es_archives/packetbeat/dns'));
+ before(
+ async () => await esArchiver.load('x-pack/test/functional/es_archives/packetbeat/dns')
+ );
+ after(
+ async () => await esArchiver.unload('x-pack/test/functional/es_archives/packetbeat/dns')
+ );
const FROM = '2000-01-01T00:00:00.000Z';
const TO = '3000-01-01T00:00:00.000Z';
it('Make sure that we get Dns data and sorting by uniqueDomains ascending', async () => {
- const { body: networkDns } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
+ const networkDns = await bsearch.send({
+ supertest,
+ options: {
defaultIndex: ['packetbeat-*'],
docValueFields: [],
factoryQueryType: NetworkQueries.dns,
@@ -45,9 +50,9 @@ export default function ({ getService }: FtrProviderContext) {
to: TO,
from: FROM,
},
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
+ },
+ strategy: 'securitySolutionSearchStrategy',
+ });
expect(networkDns.edges.length).to.be(10);
expect(networkDns.totalCount).to.be(44);
@@ -58,10 +63,9 @@ export default function ({ getService }: FtrProviderContext) {
});
it('Make sure that we get Dns data and sorting by uniqueDomains descending', async () => {
- const { body: networkDns } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
+ const networkDns = await bsearch.send({
+ supertest,
+ options: {
ip: '151.205.0.17',
defaultIndex: ['packetbeat-*'],
factoryQueryType: NetworkQueries.dns,
@@ -80,9 +84,9 @@ export default function ({ getService }: FtrProviderContext) {
to: TO,
from: FROM,
},
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
+ },
+ strategy: 'securitySolutionSearchStrategy',
+ });
expect(networkDns.edges.length).to.be(10);
expect(networkDns.totalCount).to.be(44);
diff --git a/x-pack/test/api_integration/apis/security_solution/network_top_n_flow.ts b/x-pack/test/api_integration/apis/security_solution/network_top_n_flow.ts
index af8e5439074921..41b083ab90578c 100644
--- a/x-pack/test/api_integration/apis/security_solution/network_top_n_flow.ts
+++ b/x-pack/test/api_integration/apis/security_solution/network_top_n_flow.ts
@@ -12,6 +12,7 @@ import {
Direction,
FlowTargetSourceDest,
NetworkTopTablesFields,
+ NetworkTopNFlowStrategyResponse,
} from '../../../../plugins/security_solution/common/search_strategy';
import { FtrProviderContext } from '../../ftr_provider_context';
@@ -21,20 +22,24 @@ const EDGE_LENGTH = 10;
export default function ({ getService }: FtrProviderContext) {
const esArchiver = getService('esArchiver');
const supertest = getService('supertest');
+ const bsearch = getService('bsearch');
describe('Network Top N Flow', () => {
describe('With filebeat', () => {
- before(() => esArchiver.load('x-pack/test/functional/es_archives/filebeat/default'));
- after(() => esArchiver.unload('x-pack/test/functional/es_archives/filebeat/default'));
+ before(
+ async () => await esArchiver.load('x-pack/test/functional/es_archives/filebeat/default')
+ );
+ after(
+ async () => await esArchiver.unload('x-pack/test/functional/es_archives/filebeat/default')
+ );
const FROM = '2019-02-09T01:57:24.870Z';
const TO = '2019-02-12T01:57:24.870Z';
it('Make sure that we get Source NetworkTopNFlow data with bytes_in descending sort', async () => {
- const { body: networkTopNFlow } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
+ const networkTopNFlow = await bsearch.send({
+ supertest,
+ options: {
defaultIndex: ['filebeat-*'],
factoryQueryType: NetworkQueries.topNFlow,
flowTarget: FlowTargetSourceDest.source,
@@ -52,9 +57,9 @@ export default function ({ getService }: FtrProviderContext) {
},
docValueFields: [],
inspect: false,
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
+ },
+ strategy: 'securitySolutionSearchStrategy',
+ });
expect(networkTopNFlow.edges.length).to.be(EDGE_LENGTH);
expect(networkTopNFlow.totalCount).to.be(121);
@@ -70,10 +75,9 @@ export default function ({ getService }: FtrProviderContext) {
});
it('Make sure that we get Source NetworkTopNFlow data with bytes_in ascending sort ', async () => {
- const { body: networkTopNFlow } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
+ const networkTopNFlow = await bsearch.send({
+ supertest,
+ options: {
defaultIndex: ['filebeat-*'],
factoryQueryType: 'topNFlow',
filterQuery:
@@ -93,9 +97,9 @@ export default function ({ getService }: FtrProviderContext) {
},
docValueFields: [],
inspect: false,
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
+ },
+ strategy: 'securitySolutionSearchStrategy',
+ });
expect(networkTopNFlow.edges.length).to.be(EDGE_LENGTH);
expect(networkTopNFlow.totalCount).to.be(121);
@@ -111,10 +115,9 @@ export default function ({ getService }: FtrProviderContext) {
});
it('Make sure that we get Destination NetworkTopNFlow data', async () => {
- const { body: networkTopNFlow } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
+ const networkTopNFlow = await bsearch.send({
+ supertest,
+ options: {
defaultIndex: ['filebeat-*'],
factoryQueryType: 'topNFlow',
filterQuery:
@@ -134,9 +137,10 @@ export default function ({ getService }: FtrProviderContext) {
},
docValueFields: [],
inspect: false,
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
+ },
+ strategy: 'securitySolutionSearchStrategy',
+ });
+
expect(networkTopNFlow.edges.length).to.be(EDGE_LENGTH);
expect(networkTopNFlow.totalCount).to.be(154);
expect(networkTopNFlow.edges[0].node.destination!.flows).to.be(19);
@@ -146,10 +150,9 @@ export default function ({ getService }: FtrProviderContext) {
});
it('Make sure that pagination is working in NetworkTopNFlow query', async () => {
- const { body: networkTopNFlow } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
+ const networkTopNFlow = await bsearch.send({
+ supertest,
+ options: {
defaultIndex: ['filebeat-*'],
factoryQueryType: 'topNFlow',
filterQuery:
@@ -169,9 +172,9 @@ export default function ({ getService }: FtrProviderContext) {
},
docValueFields: [],
inspect: false,
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
+ },
+ strategy: 'securitySolutionSearchStrategy',
+ });
expect(networkTopNFlow.edges.length).to.be(EDGE_LENGTH);
expect(networkTopNFlow.totalCount).to.be(121);
diff --git a/x-pack/test/api_integration/apis/security_solution/overview_host.ts b/x-pack/test/api_integration/apis/security_solution/overview_host.ts
index 09bd09782d2f26..b2a32ac46c3f31 100644
--- a/x-pack/test/api_integration/apis/security_solution/overview_host.ts
+++ b/x-pack/test/api_integration/apis/security_solution/overview_host.ts
@@ -8,16 +8,24 @@
import expect from '@kbn/expect';
import { FtrProviderContext } from '../../ftr_provider_context';
-import { HostsQueries } from '../../../../plugins/security_solution/common/search_strategy';
+import {
+ HostsQueries,
+ HostsOverviewStrategyResponse,
+} from '../../../../plugins/security_solution/common/search_strategy';
export default function ({ getService }: FtrProviderContext) {
const esArchiver = getService('esArchiver');
const supertest = getService('supertest');
+ const bsearch = getService('bsearch');
describe('Overview Host', () => {
describe('With auditbeat', () => {
- before(() => esArchiver.load('x-pack/test/functional/es_archives/auditbeat/overview'));
- after(() => esArchiver.unload('x-pack/test/functional/es_archives/auditbeat/overview'));
+ before(
+ async () => await esArchiver.load('x-pack/test/functional/es_archives/auditbeat/overview')
+ );
+ after(
+ async () => await esArchiver.unload('x-pack/test/functional/es_archives/auditbeat/overview')
+ );
const FROM = '2000-01-01T00:00:00.000Z';
const TO = '3000-01-01T00:00:00.000Z';
@@ -41,12 +49,9 @@ export default function ({ getService }: FtrProviderContext) {
};
it('Make sure that we get OverviewHost data', async () => {
- const {
- body: { overviewHost },
- } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
+ const { overviewHost } = await bsearch.send({
+ supertest,
+ options: {
defaultIndex: ['auditbeat-*'],
factoryQueryType: HostsQueries.overview,
timerange: {
@@ -56,9 +61,9 @@ export default function ({ getService }: FtrProviderContext) {
},
docValueFields: [],
inspect: false,
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
+ },
+ strategy: 'securitySolutionSearchStrategy',
+ });
expect(overviewHost).to.eql(expectedResult);
});
});
diff --git a/x-pack/test/api_integration/apis/security_solution/overview_network.ts b/x-pack/test/api_integration/apis/security_solution/overview_network.ts
index 00adc903d5733d..ffee9b851ffc0d 100644
--- a/x-pack/test/api_integration/apis/security_solution/overview_network.ts
+++ b/x-pack/test/api_integration/apis/security_solution/overview_network.ts
@@ -7,16 +7,24 @@
import expect from '@kbn/expect';
import { FtrProviderContext } from '../../ftr_provider_context';
-import { NetworkQueries } from '../../../../plugins/security_solution/common/search_strategy';
+import {
+ NetworkOverviewStrategyResponse,
+ NetworkQueries,
+} from '../../../../plugins/security_solution/common/search_strategy';
export default function ({ getService }: FtrProviderContext) {
const esArchiver = getService('esArchiver');
const supertest = getService('supertest');
+ const bsearch = getService('bsearch');
describe('Overview Network', () => {
describe('With filebeat', () => {
- before(() => esArchiver.load('x-pack/test/functional/es_archives/filebeat/default'));
- after(() => esArchiver.unload('x-pack/test/functional/es_archives/filebeat/default'));
+ before(
+ async () => await esArchiver.load('x-pack/test/functional/es_archives/filebeat/default')
+ );
+ after(
+ async () => await esArchiver.unload('x-pack/test/functional/es_archives/filebeat/default')
+ );
const FROM = '2000-01-01T00:00:00.000Z';
const TO = '3000-01-01T00:00:00.000Z';
@@ -34,12 +42,9 @@ export default function ({ getService }: FtrProviderContext) {
};
it('Make sure that we get OverviewNetwork data', async () => {
- const {
- body: { overviewNetwork },
- } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
+ const { overviewNetwork } = await bsearch.send({
+ supertest,
+ options: {
defaultIndex: ['filebeat-*'],
factoryQueryType: NetworkQueries.overview,
timerange: {
@@ -49,16 +54,21 @@ export default function ({ getService }: FtrProviderContext) {
},
docValueFields: [],
inspect: false,
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
+ },
+ strategy: 'securitySolutionSearchStrategy',
+ });
expect(overviewNetwork).to.eql(expectedResult);
});
});
describe('With packetbeat', () => {
- before(() => esArchiver.load('x-pack/test/functional/es_archives/packetbeat/overview'));
- after(() => esArchiver.unload('x-pack/test/functional/es_archives/packetbeat/overview'));
+ before(
+ async () => await esArchiver.load('x-pack/test/functional/es_archives/packetbeat/overview')
+ );
+ after(
+ async () =>
+ await esArchiver.unload('x-pack/test/functional/es_archives/packetbeat/overview')
+ );
const FROM = '2000-01-01T00:00:00.000Z';
const TO = '3000-01-01T00:00:00.000Z';
@@ -75,12 +85,9 @@ export default function ({ getService }: FtrProviderContext) {
};
it('Make sure that we get OverviewNetwork data', async () => {
- const {
- body: { overviewNetwork },
- } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
+ const { overviewNetwork } = await bsearch.send({
+ supertest,
+ options: {
defaultIndex: ['packetbeat-*'],
factoryQueryType: NetworkQueries.overview,
timerange: {
@@ -90,17 +97,20 @@ export default function ({ getService }: FtrProviderContext) {
},
docValueFields: [],
inspect: false,
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
-
+ },
+ strategy: 'securitySolutionSearchStrategy',
+ });
expect(overviewNetwork).to.eql(expectedResult);
});
});
describe('With auditbeat', () => {
- before(() => esArchiver.load('x-pack/test/functional/es_archives/auditbeat/overview'));
- after(() => esArchiver.unload('x-pack/test/functional/es_archives/auditbeat/overview'));
+ before(
+ async () => await esArchiver.load('x-pack/test/functional/es_archives/auditbeat/overview')
+ );
+ after(
+ async () => await esArchiver.unload('x-pack/test/functional/es_archives/auditbeat/overview')
+ );
const FROM = '2000-01-01T00:00:00.000Z';
const TO = '3000-01-01T00:00:00.000Z';
@@ -117,12 +127,9 @@ export default function ({ getService }: FtrProviderContext) {
};
it('Make sure that we get OverviewNetwork data', async () => {
- const {
- body: { overviewNetwork },
- } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
+ const { overviewNetwork } = await bsearch.send({
+ supertest,
+ options: {
defaultIndex: ['auditbeat-*'],
factoryQueryType: NetworkQueries.overview,
timerange: {
@@ -132,9 +139,9 @@ export default function ({ getService }: FtrProviderContext) {
},
docValueFields: [],
inspect: false,
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
+ },
+ strategy: 'securitySolutionSearchStrategy',
+ });
expect(overviewNetwork).to.eql(expectedResult);
});
});
diff --git a/x-pack/test/api_integration/apis/security_solution/timeline_details.ts b/x-pack/test/api_integration/apis/security_solution/timeline_details.ts
index 3aefd9f8b597ab..9f1b5fccd9d1af 100644
--- a/x-pack/test/api_integration/apis/security_solution/timeline_details.ts
+++ b/x-pack/test/api_integration/apis/security_solution/timeline_details.ts
@@ -7,7 +7,11 @@
import expect from '@kbn/expect';
import { sortBy } from 'lodash';
-import { TimelineEventsQueries } from '../../../../plugins/security_solution/common/search_strategy';
+import {
+ TimelineEventsQueries,
+ TimelineEventsDetailsStrategyResponse,
+ TimelineKpiStrategyResponse,
+} from '../../../../plugins/security_solution/common/search_strategy';
import { FtrProviderContext } from '../../ftr_provider_context';
@@ -668,54 +672,49 @@ const EXPECTED_KPI_COUNTS = {
};
export default function ({ getService }: FtrProviderContext) {
- const retry = getService('retry');
const esArchiver = getService('esArchiver');
const supertest = getService('supertest');
+ const bsearch = getService('bsearch');
describe('Timeline Details', () => {
- before(() => esArchiver.load('x-pack/test/functional/es_archives/filebeat/default'));
- after(() => esArchiver.unload('x-pack/test/functional/es_archives/filebeat/default'));
+ before(
+ async () => await esArchiver.load('x-pack/test/functional/es_archives/filebeat/default')
+ );
+ after(
+ async () => await esArchiver.unload('x-pack/test/functional/es_archives/filebeat/default')
+ );
it('Make sure that we get Event Details data', async () => {
- await retry.try(async () => {
- const {
- body: { data: detailsData },
- } = await supertest
- .post('/internal/search/timelineSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
- factoryQueryType: TimelineEventsQueries.details,
- docValueFields: [],
- indexName: INDEX_NAME,
- inspect: false,
- eventId: ID,
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
- expect(sortBy(detailsData, 'field')).to.eql(sortBy(EXPECTED_DATA, 'field'));
+ const { data: detailsData } = await bsearch.send({
+ supertest,
+ options: {
+ factoryQueryType: TimelineEventsQueries.details,
+ docValueFields: [],
+ indexName: INDEX_NAME,
+ inspect: false,
+ eventId: ID,
+ },
+ strategy: 'timelineSearchStrategy',
});
+ expect(sortBy(detailsData, 'field')).to.eql(sortBy(EXPECTED_DATA, 'field'));
});
it('Make sure that we get kpi data', async () => {
- await retry.try(async () => {
- const {
- body: { destinationIpCount, hostCount, processCount, sourceIpCount, userCount },
- } = await supertest
- .post('/internal/search/timelineSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
+ const { destinationIpCount, hostCount, processCount, sourceIpCount, userCount } =
+ await bsearch.send({
+ supertest,
+ options: {
factoryQueryType: TimelineEventsQueries.kpi,
docValueFields: [],
indexName: INDEX_NAME,
inspect: false,
eventId: ID,
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
- expect({ destinationIpCount, hostCount, processCount, sourceIpCount, userCount }).to.eql(
- EXPECTED_KPI_COUNTS
- );
- });
+ },
+ strategy: 'timelineSearchStrategy',
+ });
+ expect({ destinationIpCount, hostCount, processCount, sourceIpCount, userCount }).to.eql(
+ EXPECTED_KPI_COUNTS
+ );
});
});
}
diff --git a/x-pack/test/api_integration/apis/security_solution/tls.ts b/x-pack/test/api_integration/apis/security_solution/tls.ts
index 9fa251ded4e6b1..c872844cb3d463 100644
--- a/x-pack/test/api_integration/apis/security_solution/tls.ts
+++ b/x-pack/test/api_integration/apis/security_solution/tls.ts
@@ -11,6 +11,7 @@ import {
Direction,
NetworkTlsFields,
FlowTarget,
+ NetworkTlsStrategyResponse,
} from '../../../../plugins/security_solution/common/search_strategy';
import { FtrProviderContext } from '../../ftr_provider_context';
@@ -83,17 +84,21 @@ const expectedOverviewSourceResult = {
export default function ({ getService }: FtrProviderContext) {
const esArchiver = getService('esArchiver');
const supertest = getService('supertest');
+ const bsearch = getService('bsearch');
describe('Tls Test with Packetbeat', () => {
describe('Tls Test', () => {
- before(() => esArchiver.load('x-pack/test/functional/es_archives/packetbeat/tls'));
- after(() => esArchiver.unload('x-pack/test/functional/es_archives/packetbeat/tls'));
+ before(
+ async () => await esArchiver.load('x-pack/test/functional/es_archives/packetbeat/tls')
+ );
+ after(
+ async () => await esArchiver.unload('x-pack/test/functional/es_archives/packetbeat/tls')
+ );
it('Ensure data is returned for FlowTarget.Source', async () => {
- const { body: tls } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
+ const tls = await bsearch.send({
+ supertest,
+ options: {
factoryQueryType: NetworkQueries.tls,
timerange: {
interval: '12h',
@@ -112,19 +117,18 @@ export default function ({ getService }: FtrProviderContext) {
defaultIndex: ['packetbeat-*'],
docValueFields: [],
inspect: false,
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
+ },
+ strategy: 'securitySolutionSearchStrategy',
+ });
expect(tls.edges.length).to.be(1);
expect(tls.totalCount).to.be(1);
expect(tls.edges[0].node).to.eql(expectedResult);
});
it('Ensure data is returned for FlowTarget.Destination', async () => {
- const { body: tls } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
+ const tls = await bsearch.send({
+ supertest,
+ options: {
factoryQueryType: NetworkQueries.tls,
timerange: {
interval: '12h',
@@ -143,9 +147,9 @@ export default function ({ getService }: FtrProviderContext) {
defaultIndex: ['packetbeat-*'],
docValueFields: [],
inspect: false,
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
+ },
+ strategy: 'securitySolutionSearchStrategy',
+ });
expect(tls.edges.length).to.be(1);
expect(tls.totalCount).to.be(1);
expect(tls.edges[0].node).to.eql(expectedResult);
@@ -153,14 +157,17 @@ export default function ({ getService }: FtrProviderContext) {
});
describe('Tls Overview Test', () => {
- before(() => esArchiver.load('x-pack/test/functional/es_archives/packetbeat/tls'));
- after(() => esArchiver.unload('x-pack/test/functional/es_archives/packetbeat/tls'));
+ before(
+ async () => await esArchiver.load('x-pack/test/functional/es_archives/packetbeat/tls')
+ );
+ after(
+ async () => await esArchiver.unload('x-pack/test/functional/es_archives/packetbeat/tls')
+ );
it('Ensure data is returned for FlowTarget.Source', async () => {
- const { body: tls } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
+ const tls = await bsearch.send({
+ supertest,
+ options: {
factoryQueryType: NetworkQueries.tls,
timerange: {
interval: '12h',
@@ -179,18 +186,18 @@ export default function ({ getService }: FtrProviderContext) {
defaultIndex: ['packetbeat-*'],
docValueFields: [],
inspect: false,
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
+ },
+ strategy: 'securitySolutionSearchStrategy',
+ });
+
expect(tls.pageInfo).to.eql(expectedOverviewSourceResult.pageInfo);
expect(tls.edges[0]).to.eql(expectedOverviewSourceResult.edges[0]);
});
it('Ensure data is returned for FlowTarget.Destination', async () => {
- const { body: tls } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
+ const tls = await bsearch.send({
+ supertest,
+ options: {
factoryQueryType: NetworkQueries.tls,
timerange: {
interval: '12h',
@@ -209,9 +216,10 @@ export default function ({ getService }: FtrProviderContext) {
defaultIndex: ['packetbeat-*'],
docValueFields: [],
inspect: false,
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
+ },
+ strategy: 'securitySolutionSearchStrategy',
+ });
+
expect(tls.pageInfo).to.eql(expectedOverviewDestinationResult.pageInfo);
expect(tls.edges[0]).to.eql(expectedOverviewDestinationResult.edges[0]);
});
diff --git a/x-pack/test/api_integration/apis/security_solution/uncommon_processes.ts b/x-pack/test/api_integration/apis/security_solution/uncommon_processes.ts
index d39cc0afb6461a..a6749b27030e1b 100644
--- a/x-pack/test/api_integration/apis/security_solution/uncommon_processes.ts
+++ b/x-pack/test/api_integration/apis/security_solution/uncommon_processes.ts
@@ -13,10 +13,6 @@ import {
} from '../../../../plugins/security_solution/common/search_strategy';
import { FtrProviderContext } from '../../ftr_provider_context';
-interface UncommonProcessesResponse {
- body: HostsUncommonProcessesStrategyResponse;
-}
-
const FROM = '2000-01-01T00:00:00.000Z';
const TO = '3000-01-01T00:00:00.000Z';
@@ -24,24 +20,51 @@ const TO = '3000-01-01T00:00:00.000Z';
const TOTAL_COUNT = 3;
export default function ({ getService }: FtrProviderContext) {
- const retry = getService('retry');
const esArchiver = getService('esArchiver');
const supertest = getService('supertest');
+ const bsearch = getService('bsearch');
describe('uncommon_processes', () => {
- before(() =>
- esArchiver.load('x-pack/test/functional/es_archives/auditbeat/uncommon_processes')
+ before(
+ async () =>
+ await esArchiver.load('x-pack/test/functional/es_archives/auditbeat/uncommon_processes')
);
- after(() =>
- esArchiver.unload('x-pack/test/functional/es_archives/auditbeat/uncommon_processes')
+ after(
+ async () =>
+ await esArchiver.unload('x-pack/test/functional/es_archives/auditbeat/uncommon_processes')
);
it('should return an edge of length 1 when given a pagination of length 1', async () => {
- await retry.try(async () => {
- const response = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
+ const response = await bsearch.send({
+ supertest,
+ options: {
+ factoryQueryType: HostsQueries.uncommonProcesses,
+ sourceId: 'default',
+ timerange: {
+ interval: '12h',
+ to: TO,
+ from: FROM,
+ },
+ pagination: {
+ activePage: 0,
+ cursorStart: 0,
+ fakePossibleCount: 3,
+ querySize: 1,
+ },
+ defaultIndex: ['auditbeat-uncommon-processes'],
+ docValueFields: [],
+ inspect: false,
+ },
+ strategy: 'securitySolutionSearchStrategy',
+ });
+ expect(response.edges.length).to.be(1);
+ });
+
+ describe('when given a pagination of length 2', () => {
+ it('should return an edge of length 2 ', async () => {
+ const response = await bsearch.send({
+ supertest,
+ options: {
factoryQueryType: HostsQueries.uncommonProcesses,
sourceId: 'default',
timerange: {
@@ -53,84 +76,51 @@ export default function ({ getService }: FtrProviderContext) {
activePage: 0,
cursorStart: 0,
fakePossibleCount: 3,
- querySize: 1,
+ querySize: 2,
},
defaultIndex: ['auditbeat-uncommon-processes'],
docValueFields: [],
inspect: false,
- })
- .expect(200);
- expect(response!.body.edges.length).to.be(1);
- });
- });
-
- describe('when given a pagination of length 2', () => {
- it('should return an edge of length 2 ', async () => {
- await retry.try(async () => {
- const response = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
- factoryQueryType: HostsQueries.uncommonProcesses,
- sourceId: 'default',
- timerange: {
- interval: '12h',
- to: TO,
- from: FROM,
- },
- pagination: {
- activePage: 0,
- cursorStart: 0,
- fakePossibleCount: 3,
- querySize: 2,
- },
- defaultIndex: ['auditbeat-uncommon-processes'],
- docValueFields: [],
- inspect: false,
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
- expect(response!.body.edges.length).to.be(2);
+ },
+ strategy: 'securitySolutionSearchStrategy',
});
+ expect(response.edges.length).to.be(2);
});
});
describe('when given a pagination of length 1', () => {
- let response: null | UncommonProcessesResponse = null;
+ let response: HostsUncommonProcessesStrategyResponse | null = null;
before(async () => {
- await retry.try(async () => {
- response = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
- factoryQueryType: HostsQueries.uncommonProcesses,
- sourceId: 'default',
- timerange: {
- interval: '12h',
- to: TO,
- from: FROM,
- },
- pagination: {
- activePage: 0,
- cursorStart: 0,
- fakePossibleCount: 3,
- querySize: 1,
- },
- defaultIndex: ['auditbeat-uncommon-processes'],
- docValueFields: [],
- inspect: false,
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
+ response = await bsearch.send({
+ supertest,
+ options: {
+ factoryQueryType: HostsQueries.uncommonProcesses,
+ sourceId: 'default',
+ timerange: {
+ interval: '12h',
+ to: TO,
+ from: FROM,
+ },
+ pagination: {
+ activePage: 0,
+ cursorStart: 0,
+ fakePossibleCount: 3,
+ querySize: 1,
+ },
+ defaultIndex: ['auditbeat-uncommon-processes'],
+ docValueFields: [],
+ inspect: false,
+ },
+ strategy: 'securitySolutionSearchStrategy',
});
});
it('should return an edge of length 1 ', () => {
- expect(response!.body.edges.length).to.be(1);
+ expect(response?.edges.length).to.be(1);
});
it('should return a total count of elements', () => {
- expect(response!.body.totalCount).to.be(TOTAL_COUNT);
+ expect(response?.totalCount).to.be(TOTAL_COUNT);
});
it('should return a single data set with pagination of 1', () => {
@@ -152,7 +142,7 @@ export default function ({ getService }: FtrProviderContext) {
},
],
};
- expect(response!.body.edges[0].node).to.eql(expected);
+ expect(response?.edges[0].node).to.eql(expected);
});
});
});
diff --git a/x-pack/test/api_integration/apis/security_solution/users.ts b/x-pack/test/api_integration/apis/security_solution/users.ts
index 84335cc2695ce1..d592c99bf006f1 100644
--- a/x-pack/test/api_integration/apis/security_solution/users.ts
+++ b/x-pack/test/api_integration/apis/security_solution/users.ts
@@ -11,6 +11,7 @@ import {
Direction,
NetworkUsersFields,
FlowTarget,
+ NetworkUsersStrategyResponse,
} from '../../../../plugins/security_solution/common/search_strategy';
import { FtrProviderContext } from '../../ftr_provider_context';
@@ -20,53 +21,52 @@ const TO = '3000-01-01T00:00:00.000Z';
const IP = '0.0.0.0';
export default function ({ getService }: FtrProviderContext) {
- const retry = getService('retry');
const esArchiver = getService('esArchiver');
const supertest = getService('supertest');
+ const bsearch = getService('bsearch');
+
describe('Users', () => {
describe('With auditbeat', () => {
- before(() => esArchiver.load('x-pack/test/functional/es_archives/auditbeat/users'));
- after(() => esArchiver.unload('x-pack/test/functional/es_archives/auditbeat/users'));
+ before(
+ async () => await esArchiver.load('x-pack/test/functional/es_archives/auditbeat/users')
+ );
+ after(
+ async () => await esArchiver.unload('x-pack/test/functional/es_archives/auditbeat/users')
+ );
it('Ensure data is returned from auditbeat', async () => {
- await retry.try(async () => {
- const { body: users } = await supertest
- .post('/internal/search/securitySolutionSearchStrategy/')
- .set('kbn-xsrf', 'true')
- .send({
- factoryQueryType: NetworkQueries.users,
- sourceId: 'default',
- timerange: {
- interval: '12h',
- to: TO,
- from: FROM,
- },
- defaultIndex: ['auditbeat-users'],
- docValueFields: [],
- ip: IP,
- flowTarget: FlowTarget.destination,
- sort: { field: NetworkUsersFields.name, direction: Direction.asc },
- pagination: {
- activePage: 0,
- cursorStart: 0,
- fakePossibleCount: 30,
- querySize: 10,
- },
- inspect: false,
- /* We need a very long timeout to avoid returning just partial data.
- ** https://github.com/elastic/kibana/blob/master/x-pack/test/api_integration/apis/search/search.ts#L18
- */
- wait_for_completion_timeout: '10s',
- })
- .expect(200);
- expect(users.edges.length).to.be(1);
- expect(users.totalCount).to.be(1);
- expect(users.edges[0].node.user!.id).to.eql(['0']);
- expect(users.edges[0].node.user!.name).to.be('root');
- expect(users.edges[0].node.user!.groupId).to.eql(['0']);
- expect(users.edges[0].node.user!.groupName).to.eql(['root']);
- expect(users.edges[0].node.user!.count).to.be(1);
+ const users = await bsearch.send({
+ supertest,
+ options: {
+ factoryQueryType: NetworkQueries.users,
+ sourceId: 'default',
+ timerange: {
+ interval: '12h',
+ to: TO,
+ from: FROM,
+ },
+ defaultIndex: ['auditbeat-users'],
+ docValueFields: [],
+ ip: IP,
+ flowTarget: FlowTarget.destination,
+ sort: { field: NetworkUsersFields.name, direction: Direction.asc },
+ pagination: {
+ activePage: 0,
+ cursorStart: 0,
+ fakePossibleCount: 30,
+ querySize: 10,
+ },
+ inspect: false,
+ },
+ strategy: 'securitySolutionSearchStrategy',
});
+ expect(users.edges.length).to.be(1);
+ expect(users.totalCount).to.be(1);
+ expect(users.edges[0].node.user?.id).to.eql(['0']);
+ expect(users.edges[0].node.user?.name).to.be('root');
+ expect(users.edges[0].node.user?.groupId).to.eql(['0']);
+ expect(users.edges[0].node.user?.groupName).to.eql(['root']);
+ expect(users.edges[0].node.user?.count).to.be(1);
});
});
});
diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/create_endpoint_exceptions.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/create_endpoint_exceptions.ts
index d5e623989b4606..6c6fcc366782af 100644
--- a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/create_endpoint_exceptions.ts
+++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/create_endpoint_exceptions.ts
@@ -70,8 +70,7 @@ export default ({ getService }: FtrProviderContext) => {
const supertest = getService('supertest');
const esArchiver = getService('esArchiver');
- // Flaky
- describe.skip('Rule exception operators for endpoints', () => {
+ describe('Rule exception operators for endpoints', () => {
before(async () => {
await esArchiver.load(
'x-pack/test/functional/es_archives/rule_exceptions/endpoint_without_host_type'
@@ -113,7 +112,7 @@ export default ({ getService }: FtrProviderContext) => {
os: { type: 'linux' },
},
{
- os: { type: 'windows' },
+ os: { type: 'macos' },
},
{
os: { type: 'windows' },
@@ -135,7 +134,7 @@ export default ({ getService }: FtrProviderContext) => {
os: { name: 'Linux' },
},
{
- os: { name: 'Windows' },
+ os: { name: 'Macos' },
},
{
os: { name: 'Windows' },
@@ -174,7 +173,7 @@ export default ({ getService }: FtrProviderContext) => {
os: { name: 'Linux' },
},
{
- os: { name: 'Windows' },
+ os: { name: 'Macos' },
},
{
os: { name: 'Windows' },
@@ -210,7 +209,7 @@ export default ({ getService }: FtrProviderContext) => {
os: { name: 'Linux' },
},
{
- os: { name: 'Windows' },
+ os: { name: 'Macos' },
},
{
os: { name: 'Windows' },
@@ -336,7 +335,7 @@ export default ({ getService }: FtrProviderContext) => {
os: { type: 'linux' },
},
{
- os: { type: 'windows' },
+ os: { type: 'macos' },
},
{
os: { type: 'windows' },
@@ -372,7 +371,7 @@ export default ({ getService }: FtrProviderContext) => {
os: { type: 'linux' },
},
{
- os: { type: 'windows' },
+ os: { type: 'macos' },
},
{
os: { type: 'windows' },
@@ -501,10 +500,10 @@ export default ({ getService }: FtrProviderContext) => {
os: { name: 'Linux' },
},
{
- os: { name: 'Windows' },
+ os: { type: 'macos' },
},
{
- os: { type: 'windows' },
+ os: { name: 'Macos' },
},
{
os: { type: 'windows' },
@@ -546,10 +545,10 @@ export default ({ getService }: FtrProviderContext) => {
os: { name: 'Linux' },
},
{
- os: { name: 'Windows' },
+ os: { type: 'macos' },
},
{
- os: { type: 'windows' },
+ os: { name: 'Macos' },
},
{
os: { type: 'windows' },
@@ -876,7 +875,7 @@ export default ({ getService }: FtrProviderContext) => {
os: { type: 'linux' },
},
{
- os: { type: 'windows' },
+ os: { type: 'macos' },
},
{
os: { type: 'windows' },
diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/exception_operators_data_types/ip_array.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/exception_operators_data_types/ip_array.ts
index 89f7693e723589..efff288fddac28 100644
--- a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/exception_operators_data_types/ip_array.ts
+++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/exception_operators_data_types/ip_array.ts
@@ -508,6 +508,7 @@ export default ({ getService }: FtrProviderContext) => {
],
]);
await waitForRuleSuccessOrStatus(supertest, id);
+ await waitForSignalsToBePresent(supertest, 1, [id]);
const signalsOpen = await getSignalsById(supertest, id);
const ips = signalsOpen.hits.hits.map((hit) => hit._source?.ip).sort();
expect(ips.flat(Number.MAX_SAFE_INTEGER)).to.eql([]);
diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/exception_operators_data_types/text.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/exception_operators_data_types/text.ts
index 9fd733789588fa..ff2f6806540470 100644
--- a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/exception_operators_data_types/text.ts
+++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/exception_operators_data_types/text.ts
@@ -426,9 +426,7 @@ export default ({ getService }: FtrProviderContext) => {
expect(hits).to.eql(['word four']);
});
- // This test is unreliable due to a race condition... we don't know if the rule ran and
- // generated 0 signals, or if the index hasn't refreshed yet.
- it.skip('should filter 4 text if all are set as exceptions', async () => {
+ it('should filter 4 text if all are set as exceptions', async () => {
const rule = getRuleForSignalTesting(['text']);
const { id } = await createRuleWithExceptionEntries(supertest, rule, [
[
@@ -448,9 +446,7 @@ export default ({ getService }: FtrProviderContext) => {
});
describe('"is not one of" operator', () => {
- // This test is unreliable due to a race condition... we don't know if the rule ran and
- // generated 0 signals, or if the index hasn't refreshed yet.
- it.skip('will return 0 results if it cannot find what it is excluding', async () => {
+ it('will return 0 results if it cannot find what it is excluding', async () => {
const rule = getRuleForSignalTesting(['text']);
const { id } = await createRuleWithExceptionEntries(supertest, rule, [
[
@@ -489,9 +485,7 @@ export default ({ getService }: FtrProviderContext) => {
});
describe('"exists" operator', () => {
- // This test is unreliable due to a race condition... we don't know if the rule ran and
- // generated 0 signals, or if the index hasn't refreshed yet.
- it.skip('will return 0 results if matching against text', async () => {
+ it('will return 0 results if matching against text', async () => {
const rule = getRuleForSignalTesting(['text']);
const { id } = await createRuleWithExceptionEntries(supertest, rule, [
[
@@ -577,7 +571,7 @@ export default ({ getService }: FtrProviderContext) => {
expect(hits).to.eql(['four', 'two']);
});
- it.skip('will return 0 results if we have a list that includes all text', async () => {
+ it('will return 0 results if we have a list that includes all text', async () => {
await importTextFile(
supertest,
'text',
diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/exception_operators_data_types/text_array.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/exception_operators_data_types/text_array.ts
index 3bcf8692d58f94..6d251246671329 100644
--- a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/exception_operators_data_types/text_array.ts
+++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/exception_operators_data_types/text_array.ts
@@ -337,6 +337,7 @@ export default ({ getService }: FtrProviderContext) => {
],
]);
await waitForRuleSuccessOrStatus(supertest, id);
+ await waitForSignalsToBePresent(supertest, 1, [id]);
const signalsOpen = await getSignalsById(supertest, id);
const hits = signalsOpen.hits.hits.map((hit) => hit._source?.text).sort();
expect(hits.flat(Number.MAX_SAFE_INTEGER)).to.eql([]);
@@ -515,6 +516,7 @@ export default ({ getService }: FtrProviderContext) => {
],
]);
await waitForRuleSuccessOrStatus(supertest, id);
+ await waitForSignalsToBePresent(supertest, 1, [id]);
const signalsOpen = await getSignalsById(supertest, id);
const hits = signalsOpen.hits.hits.map((hit) => hit._source?.text).sort();
expect(hits.flat(Number.MAX_SAFE_INTEGER)).to.eql([]);
diff --git a/x-pack/test/examples/search_examples/search_sessions_cache.ts b/x-pack/test/examples/search_examples/search_sessions_cache.ts
index 7e52849ed2a7e1..0da2de46a1f628 100644
--- a/x-pack/test/examples/search_examples/search_sessions_cache.ts
+++ b/x-pack/test/examples/search_examples/search_sessions_cache.ts
@@ -27,7 +27,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
return text;
}
- describe('Search session client side cache', () => {
+ // FLAKY: https://github.com/elastic/kibana/issues/116537
+ describe.skip('Search session client side cache', () => {
const appId = 'searchExamples';
before(async function () {
diff --git a/x-pack/test/functional/apps/index_lifecycle_management/home_page.ts b/x-pack/test/functional/apps/index_lifecycle_management/home_page.ts
index f7510c3c303184..95ddd0a7b59448 100644
--- a/x-pack/test/functional/apps/index_lifecycle_management/home_page.ts
+++ b/x-pack/test/functional/apps/index_lifecycle_management/home_page.ts
@@ -9,6 +9,7 @@ import expect from '@kbn/expect';
import { FtrProviderContext } from '../../ftr_provider_context';
const policyName = 'testPolicy1';
+const repoName = 'test';
export default ({ getPageObjects, getService }: FtrProviderContext) => {
const pageObjects = getPageObjects(['common', 'indexLifecycleManagement']);
@@ -16,12 +17,23 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
const retry = getService('retry');
const esClient = getService('es');
- // FAILING ES PROMOTION: https://github.com/elastic/kibana/issues/114473 and https://github.com/elastic/kibana/issues/114474
- describe.skip('Home page', function () {
+ describe('Home page', function () {
before(async () => {
+ await esClient.snapshot.createRepository({
+ name: repoName,
+ body: {
+ type: 'fs',
+ settings: {
+ // use one of the values defined in path.repo in test/functional/config.js
+ location: '/tmp/',
+ },
+ },
+ verify: false,
+ });
await pageObjects.common.navigateToApp('indexLifecycleManagement');
});
after(async () => {
+ await esClient.snapshot.deleteRepository({ name: repoName });
await esClient.ilm.deleteLifecycle({ name: policyName });
});
@@ -41,6 +53,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
coldEnabled: true,
frozenEnabled: true,
deleteEnabled: true,
+ snapshotRepository: repoName,
});
await retry.waitFor('navigation back to home page.', async () => {
diff --git a/x-pack/test/functional/apps/maps/sample_data.js b/x-pack/test/functional/apps/maps/sample_data.js
index a6e4500d30593b..483379b2f49144 100644
--- a/x-pack/test/functional/apps/maps/sample_data.js
+++ b/x-pack/test/functional/apps/maps/sample_data.js
@@ -108,7 +108,7 @@ export default function ({ getPageObjects, getService, updateBaselines }) {
describe('ecommerce', () => {
before(async () => {
await PageObjects.maps.loadSavedMap('[eCommerce] Orders by Country');
- await PageObjects.maps.toggleLayerVisibility('Road map');
+ await PageObjects.maps.toggleLayerVisibility('Road map - desaturated');
await PageObjects.maps.toggleLayerVisibility('United Kingdom');
await PageObjects.maps.toggleLayerVisibility('France');
await PageObjects.maps.toggleLayerVisibility('United States');
@@ -136,7 +136,7 @@ export default function ({ getPageObjects, getService, updateBaselines }) {
describe('flights', () => {
before(async () => {
await PageObjects.maps.loadSavedMap('[Flights] Origin Time Delayed');
- await PageObjects.maps.toggleLayerVisibility('Road map');
+ await PageObjects.maps.toggleLayerVisibility('Road map - desaturated');
await PageObjects.timePicker.setCommonlyUsedTime('sample_data range');
await PageObjects.maps.enterFullScreen();
await PageObjects.maps.closeLegend();
@@ -160,7 +160,7 @@ export default function ({ getPageObjects, getService, updateBaselines }) {
describe('web logs', () => {
before(async () => {
await PageObjects.maps.loadSavedMap('[Logs] Total Requests and Bytes');
- await PageObjects.maps.toggleLayerVisibility('Road map');
+ await PageObjects.maps.toggleLayerVisibility('Road map - desaturated');
await PageObjects.maps.toggleLayerVisibility('Total Requests by Destination');
await PageObjects.timePicker.setCommonlyUsedTime('sample_data range');
await PageObjects.maps.enterFullScreen();
diff --git a/x-pack/test/functional/apps/ml/anomaly_detection/forecasts.ts b/x-pack/test/functional/apps/ml/anomaly_detection/forecasts.ts
new file mode 100644
index 00000000000000..f65653e2c03c5c
--- /dev/null
+++ b/x-pack/test/functional/apps/ml/anomaly_detection/forecasts.ts
@@ -0,0 +1,116 @@
+/*
+ * 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 { FtrProviderContext } from '../../../ftr_provider_context';
+import { Job, Datafeed } from '../../../../../plugins/ml/common/types/anomaly_detection_jobs';
+
+// @ts-expect-error not full interface
+const JOB_CONFIG: Job = {
+ job_id: `fq_single_1_smv`,
+ description: 'count() on farequote dataset with 15m bucket span',
+ groups: ['farequote', 'automated', 'single-metric'],
+ analysis_config: {
+ bucket_span: '15m',
+ influencers: [],
+ detectors: [
+ {
+ function: 'count',
+ },
+ ],
+ },
+ data_description: { time_field: '@timestamp' },
+ analysis_limits: { model_memory_limit: '10mb' },
+ model_plot_config: { enabled: true },
+};
+
+// @ts-expect-error not full interface
+const DATAFEED_CONFIG: Datafeed = {
+ datafeed_id: 'datafeed-fq_single_1_smv',
+ indices: ['ft_farequote'],
+ job_id: 'fq_single_1_smv',
+ query: { bool: { must: [{ match_all: {} }] } },
+};
+
+export default function ({ getService }: FtrProviderContext) {
+ const esArchiver = getService('esArchiver');
+ const ml = getService('ml');
+
+ describe('forecasts', function () {
+ this.tags(['mlqa']);
+
+ describe('with single metric job', function () {
+ before(async () => {
+ await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote');
+ await ml.testResources.createIndexPatternIfNeeded('ft_farequote', '@timestamp');
+ await ml.testResources.setKibanaTimeZoneToUTC();
+
+ await ml.api.createAndRunAnomalyDetectionLookbackJob(JOB_CONFIG, DATAFEED_CONFIG);
+ await ml.securityUI.loginAsMlPowerUser();
+ });
+
+ after(async () => {
+ await ml.api.cleanMlIndices();
+ });
+
+ it('opens a job from job list link', async () => {
+ await ml.testExecution.logTestStep('navigate to job list');
+ await ml.navigation.navigateToMl();
+ await ml.navigation.navigateToJobManagement();
+
+ await ml.testExecution.logTestStep('open job in single metric viewer');
+ await ml.jobTable.waitForJobsToLoad();
+ await ml.jobTable.filterWithSearchString(JOB_CONFIG.job_id, 1);
+
+ await ml.jobTable.clickOpenJobInSingleMetricViewerButton(JOB_CONFIG.job_id);
+ await ml.commonUI.waitForMlLoadingIndicatorToDisappear();
+ });
+
+ it('displays job results', async () => {
+ await ml.testExecution.logTestStep('pre-fills the job selection');
+ await ml.jobSelection.assertJobSelection([JOB_CONFIG.job_id]);
+
+ await ml.testExecution.logTestStep('pre-fills the detector input');
+ await ml.singleMetricViewer.assertDetectorInputExist();
+ await ml.singleMetricViewer.assertDetectorInputValue('0');
+
+ await ml.testExecution.logTestStep('displays the chart');
+ await ml.singleMetricViewer.assertChartExist();
+
+ await ml.testExecution.logTestStep('should not display the forecasts toggle checkbox');
+ await ml.forecast.assertForecastCheckboxMissing();
+
+ await ml.testExecution.logTestStep('should open the forecasts modal');
+ await ml.forecast.assertForecastButtonExists();
+ await ml.forecast.assertForecastButtonEnabled(true);
+ await ml.forecast.openForecastModal();
+ await ml.forecast.assertForecastModalRunButtonEnabled(true);
+
+ await ml.testExecution.logTestStep('should run the forecast and close the modal');
+ await ml.forecast.clickForecastModalRunButton();
+
+ await ml.testExecution.logTestStep('should display the forecasts toggle checkbox');
+ await ml.forecast.assertForecastCheckboxExists();
+
+ await ml.testExecution.logTestStep(
+ 'should display the forecast in the single metric chart'
+ );
+ await ml.forecast.assertForecastChartElementsExists();
+
+ await ml.testExecution.logTestStep('should hide the forecast in the single metric chart');
+ await ml.forecast.clickForecastCheckbox();
+ await ml.forecast.assertForecastChartElementsHidden();
+
+ await ml.testExecution.logTestStep('should open the forecasts modal and list the forecast');
+ await ml.forecast.assertForecastButtonExists();
+ await ml.forecast.assertForecastButtonEnabled(true);
+ await ml.forecast.openForecastModal();
+ await ml.forecast.assertForecastTableExists();
+ await ml.forecast.assertForecastTableNotEmpty();
+ });
+ });
+ });
+}
diff --git a/x-pack/test/functional/apps/ml/anomaly_detection/index.ts b/x-pack/test/functional/apps/ml/anomaly_detection/index.ts
index d87da8469db118..ed5f618f86644c 100644
--- a/x-pack/test/functional/apps/ml/anomaly_detection/index.ts
+++ b/x-pack/test/functional/apps/ml/anomaly_detection/index.ts
@@ -24,5 +24,6 @@ export default function ({ loadTestFile }: FtrProviderContext) {
loadTestFile(require.resolve('./annotations'));
loadTestFile(require.resolve('./aggregated_scripted_job'));
loadTestFile(require.resolve('./custom_urls'));
+ loadTestFile(require.resolve('./forecasts'));
});
}
diff --git a/x-pack/test/functional/apps/ml/permissions/full_ml_access.ts b/x-pack/test/functional/apps/ml/permissions/full_ml_access.ts
index 448774f1a0c7f1..356e3822179647 100644
--- a/x-pack/test/functional/apps/ml/permissions/full_ml_access.ts
+++ b/x-pack/test/functional/apps/ml/permissions/full_ml_access.ts
@@ -237,11 +237,11 @@ export default function ({ getService }: FtrProviderContext) {
await ml.testExecution.logTestStep(
'should display the forecast modal with enabled run button'
);
- await ml.singleMetricViewer.assertForecastButtonExists();
- await ml.singleMetricViewer.assertForecastButtonEnabled(true);
- await ml.singleMetricViewer.openForecastModal();
- await ml.singleMetricViewer.assertForecastModalRunButtonEnabled(true);
- await ml.singleMetricViewer.closeForecastModal();
+ await ml.forecast.assertForecastButtonExists();
+ await ml.forecast.assertForecastButtonEnabled(true);
+ await ml.forecast.openForecastModal();
+ await ml.forecast.assertForecastModalRunButtonEnabled(true);
+ await ml.forecast.closeForecastModal();
});
it('should display elements on Anomaly Explorer page correctly', async () => {
diff --git a/x-pack/test/functional/apps/ml/permissions/read_ml_access.ts b/x-pack/test/functional/apps/ml/permissions/read_ml_access.ts
index b96da748507866..be57904b944514 100644
--- a/x-pack/test/functional/apps/ml/permissions/read_ml_access.ts
+++ b/x-pack/test/functional/apps/ml/permissions/read_ml_access.ts
@@ -230,11 +230,11 @@ export default function ({ getService }: FtrProviderContext) {
await ml.testExecution.logTestStep(
'should display the forecast modal with disabled run button'
);
- await ml.singleMetricViewer.assertForecastButtonExists();
- await ml.singleMetricViewer.assertForecastButtonEnabled(true);
- await ml.singleMetricViewer.openForecastModal();
- await ml.singleMetricViewer.assertForecastModalRunButtonEnabled(false);
- await ml.singleMetricViewer.closeForecastModal();
+ await ml.forecast.assertForecastButtonExists();
+ await ml.forecast.assertForecastButtonEnabled(true);
+ await ml.forecast.openForecastModal();
+ await ml.forecast.assertForecastModalRunButtonEnabled(false);
+ await ml.forecast.closeForecastModal();
});
it('should display elements on Anomaly Explorer page correctly', async () => {
diff --git a/x-pack/test/functional/services/ml/forecast.ts b/x-pack/test/functional/services/ml/forecast.ts
new file mode 100644
index 00000000000000..c26216c97adfe3
--- /dev/null
+++ b/x-pack/test/functional/services/ml/forecast.ts
@@ -0,0 +1,126 @@
+/*
+ * 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 expect from '@kbn/expect';
+
+import { FtrProviderContext } from '../../ftr_provider_context';
+
+export function MachineLearningForecastProvider({ getService }: FtrProviderContext) {
+ const testSubjects = getService('testSubjects');
+
+ return {
+ async assertForecastButtonExists() {
+ await testSubjects.existOrFail(
+ 'mlSingleMetricViewerSeriesControls > mlSingleMetricViewerButtonForecast'
+ );
+ },
+
+ async assertForecastButtonEnabled(expectedValue: boolean) {
+ const isEnabled = await testSubjects.isEnabled(
+ 'mlSingleMetricViewerSeriesControls > mlSingleMetricViewerButtonForecast'
+ );
+ expect(isEnabled).to.eql(
+ expectedValue,
+ `Expected "forecast" button to be '${expectedValue ? 'enabled' : 'disabled'}' (got '${
+ isEnabled ? 'enabled' : 'disabled'
+ }')`
+ );
+ },
+
+ async assertForecastChartElementsExists() {
+ await testSubjects.existOrFail(`mlForecastArea`, {
+ timeout: 30 * 1000,
+ });
+ await testSubjects.existOrFail(`mlForecastValuesline`, {
+ timeout: 30 * 1000,
+ });
+ await testSubjects.existOrFail(`mlForecastMarkers`, {
+ timeout: 30 * 1000,
+ });
+ },
+
+ async assertForecastChartElementsHidden() {
+ await testSubjects.missingOrFail(`mlForecastArea`, {
+ allowHidden: true,
+ timeout: 30 * 1000,
+ });
+ await testSubjects.missingOrFail(`mlForecastValuesline`, {
+ allowHidden: true,
+ timeout: 30 * 1000,
+ });
+ await testSubjects.missingOrFail(`mlForecastMarkers`, {
+ allowHidden: true,
+ timeout: 30 * 1000,
+ });
+ },
+
+ async assertForecastCheckboxExists() {
+ await testSubjects.existOrFail(`mlForecastCheckbox`, {
+ timeout: 30 * 1000,
+ });
+ },
+
+ async assertForecastCheckboxMissing() {
+ await testSubjects.missingOrFail(`mlForecastCheckbox`, {
+ timeout: 30 * 1000,
+ });
+ },
+
+ async clickForecastCheckbox() {
+ await testSubjects.click('mlForecastCheckbox');
+ },
+
+ async openForecastModal() {
+ await testSubjects.click(
+ 'mlSingleMetricViewerSeriesControls > mlSingleMetricViewerButtonForecast'
+ );
+ await testSubjects.existOrFail('mlModalForecast');
+ },
+
+ async closeForecastModal() {
+ await testSubjects.click('mlModalForecast > mlModalForecastButtonClose');
+ await this.assertForecastModalMissing();
+ },
+
+ async assertForecastModalMissing() {
+ await testSubjects.missingOrFail(`mlModalForecast`, {
+ timeout: 30 * 1000,
+ });
+ },
+
+ async assertForecastModalRunButtonEnabled(expectedValue: boolean) {
+ const isEnabled = await testSubjects.isEnabled('mlModalForecast > mlModalForecastButtonRun');
+ expect(isEnabled).to.eql(
+ expectedValue,
+ `Expected forecast "run" button to be '${expectedValue ? 'enabled' : 'disabled'}' (got '${
+ isEnabled ? 'enabled' : 'disabled'
+ }')`
+ );
+ },
+
+ async assertForecastTableExists() {
+ await testSubjects.existOrFail('mlModalForecast > mlModalForecastTable');
+ },
+
+ async clickForecastModalRunButton() {
+ await testSubjects.click('mlModalForecast > mlModalForecastButtonRun');
+ await this.assertForecastModalMissing();
+ },
+
+ async getForecastTableRows() {
+ return await testSubjects.findAll('mlModalForecastTable > ~mlForecastsListRow');
+ },
+
+ async assertForecastTableNotEmpty() {
+ const tableRows = await this.getForecastTableRows();
+ expect(tableRows.length).to.be.greaterThan(
+ 0,
+ `Forecast table should have at least one row (got '${tableRows.length}')`
+ );
+ },
+ };
+}
diff --git a/x-pack/test/functional/services/ml/index.ts b/x-pack/test/functional/services/ml/index.ts
index 17302b27822237..4b48e4c0269eb9 100644
--- a/x-pack/test/functional/services/ml/index.ts
+++ b/x-pack/test/functional/services/ml/index.ts
@@ -24,6 +24,7 @@ import { MachineLearningDataVisualizerProvider } from './data_visualizer';
import { MachineLearningDataVisualizerFileBasedProvider } from './data_visualizer_file_based';
import { MachineLearningDataVisualizerIndexBasedProvider } from './data_visualizer_index_based';
import { MachineLearningDataVisualizerIndexPatternManagementProvider } from './data_visualizer_index_pattern_management';
+import { MachineLearningForecastProvider } from './forecast';
import { MachineLearningJobManagementProvider } from './job_management';
import { MachineLearningJobSelectionProvider } from './job_selection';
import { MachineLearningJobSourceSelectionProvider } from './job_source_selection';
@@ -92,6 +93,7 @@ export function MachineLearningProvider(context: FtrProviderContext) {
const dataVisualizerIndexPatternManagement =
MachineLearningDataVisualizerIndexPatternManagementProvider(context, dataVisualizerTable);
+ const forecast = MachineLearningForecastProvider(context);
const jobAnnotations = MachineLearningJobAnnotationsProvider(context);
const jobManagement = MachineLearningJobManagementProvider(context, api);
const jobSelection = MachineLearningJobSelectionProvider(context);
@@ -145,6 +147,7 @@ export function MachineLearningProvider(context: FtrProviderContext) {
dataVisualizerIndexBased,
dataVisualizerIndexPatternManagement,
dataVisualizerTable,
+ forecast,
jobAnnotations,
jobManagement,
jobSelection,
diff --git a/x-pack/test/functional/services/ml/security_common.ts b/x-pack/test/functional/services/ml/security_common.ts
index 54d2fa48a826f0..925565143bda0b 100644
--- a/x-pack/test/functional/services/ml/security_common.ts
+++ b/x-pack/test/functional/services/ml/security_common.ts
@@ -58,7 +58,7 @@ export function MachineLearningSecurityCommonProvider({ getService }: FtrProvide
{
name: 'ft_ml_ui_extras',
elasticsearch: {
- cluster: ['manage_ingest_pipelines', 'monitor'],
+ cluster: ['manage_ingest_pipelines'],
},
kibana: [],
},
diff --git a/x-pack/test/functional/services/ml/single_metric_viewer.ts b/x-pack/test/functional/services/ml/single_metric_viewer.ts
index ac3fd67e3f94e8..29f1ded74debaa 100644
--- a/x-pack/test/functional/services/ml/single_metric_viewer.ts
+++ b/x-pack/test/functional/services/ml/single_metric_viewer.ts
@@ -22,24 +22,6 @@ export function MachineLearningSingleMetricViewerProvider(
await testSubjects.existOrFail('mlNoSingleMetricJobsFound');
},
- async assertForecastButtonExists() {
- await testSubjects.existOrFail(
- 'mlSingleMetricViewerSeriesControls > mlSingleMetricViewerButtonForecast'
- );
- },
-
- async assertForecastButtonEnabled(expectedValue: boolean) {
- const isEnabled = await testSubjects.isEnabled(
- 'mlSingleMetricViewerSeriesControls > mlSingleMetricViewerButtonForecast'
- );
- expect(isEnabled).to.eql(
- expectedValue,
- `Expected "forecast" button to be '${expectedValue ? 'enabled' : 'disabled'}' (got '${
- isEnabled ? 'enabled' : 'disabled'
- }')`
- );
- },
-
async assertDetectorInputExist() {
await testSubjects.existOrFail(
'mlSingleMetricViewerSeriesControls > mlSingleMetricViewerDetectorSelect'
@@ -97,28 +79,6 @@ export function MachineLearningSingleMetricViewerProvider(
});
},
- async openForecastModal() {
- await testSubjects.click(
- 'mlSingleMetricViewerSeriesControls > mlSingleMetricViewerButtonForecast'
- );
- await testSubjects.existOrFail('mlModalForecast');
- },
-
- async closeForecastModal() {
- await testSubjects.click('mlModalForecast > mlModalForecastButtonClose');
- await testSubjects.missingOrFail('mlModalForecast');
- },
-
- async assertForecastModalRunButtonEnabled(expectedValue: boolean) {
- const isEnabled = await testSubjects.isEnabled('mlModalForecast > mlModalForecastButtonRun');
- expect(isEnabled).to.eql(
- expectedValue,
- `Expected forecast "run" button to be '${expectedValue ? 'enabled' : 'disabled'}' (got '${
- isEnabled ? 'enabled' : 'disabled'
- }')`
- );
- },
-
async openAnomalyExplorer() {
await testSubjects.click('mlAnomalyResultsViewSelectorExplorer');
await testSubjects.existOrFail('mlPageAnomalyExplorer');
diff --git a/x-pack/test/load/runner.ts b/x-pack/test/load/runner.ts
index 0bea5992f55394..c48a8e33d6eef6 100644
--- a/x-pack/test/load/runner.ts
+++ b/x-pack/test/load/runner.ts
@@ -28,7 +28,11 @@ if (!Fs.existsSync(gatlingProjectRootPath)) {
);
}
-const dropEmptyLines = (s: string) => s.split(',').filter((i) => i.length > 0);
+const dropEmptyLines = (s: string) =>
+ s
+ .split(',')
+ .filter((i) => i.length > 0)
+ .map((i) => (i.includes('.') ? i : `branch.${i}`));
const simulationClasses = dropEmptyLines(simulationEntry);
const simulationsRootPath = resolve(gatlingProjectRootPath, baseSimulationPath);
diff --git a/x-pack/test/reporting_api_integration/reporting_and_security/index.ts b/x-pack/test/reporting_api_integration/reporting_and_security/index.ts
index 159115e2054e1e..f6654ff5a6b1d4 100644
--- a/x-pack/test/reporting_api_integration/reporting_and_security/index.ts
+++ b/x-pack/test/reporting_api_integration/reporting_and_security/index.ts
@@ -30,6 +30,5 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) {
loadTestFile(require.resolve('./spaces'));
loadTestFile(require.resolve('./usage'));
loadTestFile(require.resolve('./ilm_migration_apis'));
- loadTestFile(require.resolve('./search_frozen_indices'));
});
}
diff --git a/x-pack/test/reporting_api_integration/reporting_and_security/search_frozen_indices.ts b/x-pack/test/reporting_api_integration/reporting_and_security/search_frozen_indices.ts
deleted file mode 100644
index daa749649e250e..00000000000000
--- a/x-pack/test/reporting_api_integration/reporting_and_security/search_frozen_indices.ts
+++ /dev/null
@@ -1,127 +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; you may not use this file except in compliance with the Elastic License
- * 2.0.
- */
-
-import expect from '@kbn/expect';
-import { FtrProviderContext } from '../ftr_provider_context';
-
-// eslint-disable-next-line import/no-default-export
-export default function ({ getService }: FtrProviderContext) {
- const kibanaServer = getService('kibanaServer');
- const supertestSvc = getService('supertest');
- const esSupertest = getService('esSupertest');
- const indexPatternId = 'cool-test-index-pattern';
-
- async function callExportAPI() {
- const job = {
- browserTimezone: 'UTC',
- columns: ['@timestamp', 'ip', 'utilization'],
- searchSource: {
- fields: [{ field: '*', include_unmapped: 'true' }],
- filter: [
- {
- meta: { field: '@timestamp', index: indexPatternId, params: {} },
- range: {
- '@timestamp': {
- format: 'strict_date_optional_time',
- gte: '2020-08-24T00:00:00.000Z',
- lte: '2022-08-24T21:40:48.346Z',
- },
- },
- },
- ],
- index: indexPatternId,
- parent: { filter: [], index: indexPatternId, query: { language: 'kuery', query: '' } },
- sort: [{ '@timestamp': 'desc' }],
- trackTotalHits: true,
- },
- title: 'Test search',
- };
-
- return await supertestSvc
- .post(`/api/reporting/v1/generate/immediate/csv_searchsource`)
- .set('kbn-xsrf', 'xxx')
- .send(job);
- }
-
- describe('Frozen indices search', () => {
- const reset = async () => {
- await kibanaServer.uiSettings.replace({ 'search:includeFrozen': false });
- try {
- await esSupertest.delete('/test1,test2,test3');
- await kibanaServer.savedObjects.delete({ type: 'index-pattern', id: indexPatternId });
- } catch (err) {
- // ignore 404 error
- }
- };
-
- before(reset);
- after(reset);
-
- it('Search includes frozen indices based on Advanced Setting', async () => {
- await kibanaServer.uiSettings.update({ 'csv:quoteValues': true });
-
- // setup: add multiple indices of test data
- await Promise.all([
- esSupertest
- .post('/test1/_doc')
- .send({ '@timestamp': '2021-08-24T21:36:40Z', ip: '43.98.8.183', utilization: 18725 }),
- esSupertest
- .post('/test2/_doc')
- .send({ '@timestamp': '2021-08-21T09:36:40Z', ip: '63.91.103.79', utilization: 8480 }),
- esSupertest
- .post('/test3/_doc')
- .send({ '@timestamp': '2021-08-17T21:36:40Z', ip: '139.108.162.171', utilization: 3078 }),
- ]);
- await esSupertest.post('/test*/_refresh');
-
- // setup: create index pattern
- const indexPatternCreateResponse = await kibanaServer.savedObjects.create({
- type: 'index-pattern',
- id: indexPatternId,
- overwrite: true,
- attributes: { title: 'test*', timeFieldName: '@timestamp' },
- });
- expect(indexPatternCreateResponse.id).to.be(indexPatternId);
-
- // 1. check the initial data with a CSV export
- const initialSearch = await callExportAPI();
- expectSnapshot(initialSearch.text).toMatchInline(`
- "\\"@timestamp\\",ip,utilization
- \\"Aug 24, 2021 @ 21:36:40.000\\",\\"43.98.8.183\\",\\"18,725\\"
- \\"Aug 21, 2021 @ 09:36:40.000\\",\\"63.91.103.79\\",\\"8,480\\"
- \\"Aug 17, 2021 @ 21:36:40.000\\",\\"139.108.162.171\\",\\"3,078\\"
- "
- `);
-
- // 2. freeze an index in the pattern
- await esSupertest.post('/test3/_freeze').expect(200);
- await esSupertest.post('/test*/_refresh').expect(200);
-
- // 3. recheck the search results
- const afterFreezeSearch = await callExportAPI();
- expectSnapshot(afterFreezeSearch.text).toMatchInline(`
- "\\"@timestamp\\",ip,utilization
- \\"Aug 24, 2021 @ 21:36:40.000\\",\\"43.98.8.183\\",\\"18,725\\"
- \\"Aug 21, 2021 @ 09:36:40.000\\",\\"63.91.103.79\\",\\"8,480\\"
- "
- `);
-
- // 4. update setting to allow searching frozen data
- await kibanaServer.uiSettings.update({ 'search:includeFrozen': true });
-
- // 5. recheck the search results
- const afterAllowSearch = await callExportAPI();
- expectSnapshot(afterAllowSearch.text).toMatchInline(`
- "\\"@timestamp\\",ip,utilization
- \\"Aug 24, 2021 @ 21:36:40.000\\",\\"43.98.8.183\\",\\"18,725\\"
- \\"Aug 21, 2021 @ 09:36:40.000\\",\\"63.91.103.79\\",\\"8,480\\"
- \\"Aug 17, 2021 @ 21:36:40.000\\",\\"139.108.162.171\\",\\"3,078\\"
- "
- `);
- });
- });
-}
diff --git a/x-pack/test/security_solution_endpoint/apps/endpoint/index.ts b/x-pack/test/security_solution_endpoint/apps/endpoint/index.ts
index 70d60ba5c1b67f..d1cfddbca3a9c7 100644
--- a/x-pack/test/security_solution_endpoint/apps/endpoint/index.ts
+++ b/x-pack/test/security_solution_endpoint/apps/endpoint/index.ts
@@ -15,7 +15,8 @@ import {
export default function (providerContext: FtrProviderContext) {
const { loadTestFile, getService } = providerContext;
- describe('endpoint', function () {
+ // FAILING: https://github.com/elastic/kibana/issues/72874
+ describe.skip('endpoint', function () {
const ingestManager = getService('ingestManager');
const log = getService('log');
const endpointTestResources = getService('endpointTestResources');
diff --git a/x-pack/test/timeline/security_and_spaces/tests/basic/events.ts b/x-pack/test/timeline/security_and_spaces/tests/basic/events.ts
index e44f29c41640fe..1e9cfe3eb841b3 100644
--- a/x-pack/test/timeline/security_and_spaces/tests/basic/events.ts
+++ b/x-pack/test/timeline/security_and_spaces/tests/basic/events.ts
@@ -135,6 +135,8 @@ export default ({ getService }: FtrProviderContext) => {
it(`${username} should be able to view alerts from "${featureIds.join(',')}" ${
space != null ? `in space ${space}` : 'when no space specified'
}`, async () => {
+ // This will be flake until it uses the bsearch service, but these tests aren't operational. Once you do make this operational
+ // use const bsearch = getService('bsearch');
const resp = await supertestWithoutAuth
.post(`${getSpaceUrlPrefix(space)}${TEST_URL}`)
.auth(username, password)
@@ -164,6 +166,8 @@ export default ({ getService }: FtrProviderContext) => {
it(`${username} should NOT be able to view alerts from "${featureIds.join(',')}" ${
space != null ? `in space ${space}` : 'when no space specified'
}`, async () => {
+ // This will be flake until it uses the bsearch service, but these tests aren't operational. Once you do make this operational
+ // use const bsearch = getService('bsearch');
const resp = await supertestWithoutAuth
.post(`${getSpaceUrlPrefix(space)}${TEST_URL}`)
.auth(username, password)
@@ -183,6 +187,8 @@ export default ({ getService }: FtrProviderContext) => {
it(`${username} should NOT be able to access "${featureIds.join(',')}" ${
space != null ? `in space ${space}` : 'when no space specified'
}`, async () => {
+ // This will be flake until it uses the bsearch service, but these tests aren't operational. Once you do make this operational
+ // use const bsearch = getService('bsearch');
await supertestWithoutAuth
.post(`${getSpaceUrlPrefix(space)}${TEST_URL}`)
.auth(username, password)
diff --git a/x-pack/test/timeline/security_and_spaces/tests/trial/events.ts b/x-pack/test/timeline/security_and_spaces/tests/trial/events.ts
index 0a73009196bafd..91ad87737805f7 100644
--- a/x-pack/test/timeline/security_and_spaces/tests/trial/events.ts
+++ b/x-pack/test/timeline/security_and_spaces/tests/trial/events.ts
@@ -117,6 +117,8 @@ export default ({ getService }: FtrProviderContext) => {
it(`${username} should be able to view alerts from "${featureIds.join(',')}" ${
space != null ? `in space ${space}` : 'when no space specified'
}`, async () => {
+ // This will be flake until it uses the bsearch service, but these tests aren't operational. Once you do make this operational
+ // use const bsearch = getService('bsearch');
const resp = await supertestWithoutAuth
.post(`${getSpaceUrlPrefix(space)}${TEST_URL}`)
.auth(username, password)
@@ -145,6 +147,8 @@ export default ({ getService }: FtrProviderContext) => {
it(`${username} should NOT be able to access "${featureIds.join(',')}" ${
space != null ? `in space ${space}` : 'when no space specified'
}`, async () => {
+ // This will be flake until it uses the bsearch service, but these tests aren't operational. Once you do make this operational
+ // use const bsearch = getService('bsearch');
await supertestWithoutAuth
.post(`${getSpaceUrlPrefix(space)}${TEST_URL}`)
.auth(username, password)
diff --git a/x-pack/test/upgrade/apps/maps/maps_smoke_tests.ts b/x-pack/test/upgrade/apps/maps/maps_smoke_tests.ts
index da296e5a4f60aa..fb8d8c6c59a9db 100644
--- a/x-pack/test/upgrade/apps/maps/maps_smoke_tests.ts
+++ b/x-pack/test/upgrade/apps/maps/maps_smoke_tests.ts
@@ -111,7 +111,7 @@ export default function ({
);
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.maps.waitForLayersToLoad();
- await PageObjects.maps.toggleLayerVisibility('Road map');
+ await PageObjects.maps.toggleLayerVisibility('Road map - desaturated');
await PageObjects.maps.toggleLayerVisibility('United Kingdom');
await PageObjects.maps.toggleLayerVisibility('France');
await PageObjects.maps.toggleLayerVisibility('United States');
@@ -141,7 +141,7 @@ export default function ({
);
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.maps.waitForLayersToLoad();
- await PageObjects.maps.toggleLayerVisibility('Road map');
+ await PageObjects.maps.toggleLayerVisibility('Road map - desaturated');
await PageObjects.timePicker.setCommonlyUsedTime('sample_data range');
await PageObjects.maps.enterFullScreen();
await PageObjects.maps.closeLegend();
@@ -167,7 +167,7 @@ export default function ({
);
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.maps.waitForLayersToLoad();
- await PageObjects.maps.toggleLayerVisibility('Road map');
+ await PageObjects.maps.toggleLayerVisibility('Road map - desaturated');
await PageObjects.maps.toggleLayerVisibility('Total Requests by Destination');
await PageObjects.timePicker.setCommonlyUsedTime('sample_data range');
await PageObjects.maps.enterFullScreen();
diff --git a/x-pack/test/usage_collection/test_suites/application_usage/index.ts b/x-pack/test/usage_collection/test_suites/application_usage/index.ts
index fc53c8ddf5ed37..4ba45b4bf9e126 100644
--- a/x-pack/test/usage_collection/test_suites/application_usage/index.ts
+++ b/x-pack/test/usage_collection/test_suites/application_usage/index.ts
@@ -10,7 +10,8 @@ import { FtrProviderContext } from '../../ftr_provider_context';
import { applicationUsageSchema } from '../../../../../src/plugins/kibana_usage_collection/server/collectors/application_usage/schema';
export default function ({ getService, getPageObjects }: FtrProviderContext) {
- describe('Application Usage', function () {
+ // FLAKY: https://github.com/elastic/kibana/issues/90536
+ describe.skip('Application Usage', function () {
this.tags('ciGroup1');
const { common } = getPageObjects(['common']);
const browser = getService('browser');
diff --git a/yarn.lock b/yarn.lock
index 3e4e3ad4ed2243..56d5cf17791eaf 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2337,10 +2337,10 @@
dependencies:
object-hash "^1.3.0"
-"@elastic/charts@38.0.1":
- version "38.0.1"
- resolved "https://registry.yarnpkg.com/@elastic/charts/-/charts-38.0.1.tgz#9c1db7e0f1de869e0b2b505e192bbb9d62d60dc8"
- integrity sha512-i9mIA3Ji9jSjuFDtuh9gV1xpCl3sbBEDgJiOgLVt04pr/qZH2W+tr3AV5yHvjsR7Te0Pmh/Cm5wLBvFKaI1nIA==
+"@elastic/charts@38.1.0":
+ version "38.1.0"
+ resolved "https://registry.yarnpkg.com/@elastic/charts/-/charts-38.1.0.tgz#52146564c0e399da2267c10ec4536c33e50969e4"
+ integrity sha512-u2hQ8+daCvqapKQiFqN8QHWTz3OXby5Xf/ta1Dv59KTDTFIinCZD/M8PyD3MapbKx4b67hL7UxbErqr4rZ8jeA==
dependencies:
"@popperjs/core" "^2.4.0"
chroma-js "^2.1.0"
@@ -2351,6 +2351,7 @@
d3-interpolate "^1.4.0"
d3-scale "^1.0.7"
d3-shape "^1.3.4"
+ luxon "^1.25.0"
prop-types "^15.7.2"
re-reselect "^3.4.0"
react-redux "^7.1.0"
@@ -19720,6 +19721,11 @@ lru-queue@0.1:
dependencies:
es5-ext "~0.10.2"
+luxon@^1.25.0:
+ version "1.28.0"
+ resolved "https://registry.yarnpkg.com/luxon/-/luxon-1.28.0.tgz#e7f96daad3938c06a62de0fb027115d251251fbf"
+ integrity sha512-TfTiyvZhwBYM/7QdAVDh+7dBTBA29v4ik0Ce9zda3Mnf8on1S5KJI8P2jKFZ8+5C0jhmr0KwJEO/Wdpm0VeWJQ==
+
lz-string@^1.4.4:
version "1.4.4"
resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.4.4.tgz#c0d8eaf36059f705796e1e344811cf4c498d3a26"