diff --git a/x-pack/plugins/observability/e2e/journeys/exploratory_view.ts b/x-pack/plugins/observability/e2e/journeys/exploratory_view.ts index 4d18eb3cd0b2f..cd65988e76faa 100644 --- a/x-pack/plugins/observability/e2e/journeys/exploratory_view.ts +++ b/x-pack/plugins/observability/e2e/journeys/exploratory_view.ts @@ -44,7 +44,7 @@ journey('Exploratory view', async ({ page, params }) => { }); step('renders as expected', async () => { - await page.waitForTimeout(60 * 1000); + await Promise.all([page.waitForNavigation(TIMEOUT_60_SEC), page.click('text=Explore data')]); await page.click('text=User experience (RUM)'); await page.click('[aria-label="Toggle series information"] >> text=Page views', TIMEOUT_60_SEC); await page.click('[aria-label="Edit series"]', TIMEOUT_60_SEC); diff --git a/x-pack/plugins/observability/e2e/journeys/index.ts b/x-pack/plugins/observability/e2e/journeys/index.ts index 4eb9761d18482..0119d0c4b9ed1 100644 --- a/x-pack/plugins/observability/e2e/journeys/index.ts +++ b/x-pack/plugins/observability/e2e/journeys/index.ts @@ -6,3 +6,4 @@ */ export * from './exploratory_view'; +export * from './step_duration.journey'; diff --git a/x-pack/plugins/observability/e2e/journeys/step_duration.journey.ts b/x-pack/plugins/observability/e2e/journeys/step_duration.journey.ts new file mode 100644 index 0000000000000..8618286ae4985 --- /dev/null +++ b/x-pack/plugins/observability/e2e/journeys/step_duration.journey.ts @@ -0,0 +1,91 @@ +/* + * 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 { journey, step, before } from '@elastic/synthetics'; +import { createExploratoryViewUrl } from '../../public/components/shared/exploratory_view/configurations/exploratory_view_url'; +import { loginToKibana, TIMEOUT_60_SEC, waitForLoadingToFinish } from '../utils'; + +journey('Exploratory view', async ({ page, params }) => { + before(async () => { + await waitForLoadingToFinish({ page }); + }); + + const expUrl = createExploratoryViewUrl({ + reportType: 'kpi-over-time', + allSeries: [ + { + dataType: 'synthetics', + time: { + from: 'now-10y', + to: 'now', + }, + name: 'synthetics-series-1', + breakdown: 'monitor.type', + selectedMetricField: 'monitor.duration.us', + reportDefinitions: { + 'url.full': ['ALL_VALUES'], + }, + }, + ], + }); + + const baseUrl = `${params.kibanaUrl}${expUrl}`; + + step('Go to Exploratory view', async () => { + await page.goto(baseUrl, { + waitUntil: 'networkidle', + }); + await loginToKibana({ + page, + user: { username: 'elastic', password: 'changeme' }, + dismissTour: false, + }); + }); + + step('Open exploratory view with monitor duration', async () => { + await Promise.all([ + page.waitForNavigation(TIMEOUT_60_SEC), + page.click('text=Explore data', TIMEOUT_60_SEC), + ]); + + await waitForLoadingToFinish({ page }); + await page.click('text=browser', TIMEOUT_60_SEC); + await page.click('text=http'); + await page.click('[aria-label="Remove report metric"]'); + await page.click('button:has-text("Select report metric")'); + await page.click('button:has-text("Step duration")'); + await page.click('text=Select an option: Monitor type, is selectedMonitor type >> button'); + await page.click('button[role="option"]:has-text("Step name")'); + await page.click('.euiComboBox__inputWrap'); + await page.click( + 'text=Search Monitor nameCombo box. Selected. Combo box input. Search Monitor name. Ty' + ); + await page.click('button[role="option"]:has-text("test-monitor - inline")'); + await page.click('button:has-text("Apply changes")'); + + await waitForLoadingToFinish({ page }); + + await page.click('[aria-label="series color: #54b399"]'); + await page.click('[aria-label="series color: #6092c0"]'); + await page.click('[aria-label="series color: #d36086"] path'); + await page.click('[aria-label="series color: #9170b8"]'); + await page.click('[aria-label="series color: #ca8eae"]'); + await page.click('[aria-label="series color: #d6bf57"]'); + await page.click('text=load homepage'); + await page.click('text=load homepage'); + await page.click('text=load github'); + await page.click('text=load github'); + await page.click('text=load google'); + await page.click('text=load google'); + await page.click('text=hover over products menu'); + await page.click('text=hover over products menu'); + await page.click('text=load homepage 1'); + await page.click('text=load homepage 1'); + await page.click('text=load homepage 2'); + await page.click('text=load homepage 2'); + }); +}); diff --git a/x-pack/plugins/observability/e2e/synthetics_run.ts b/x-pack/plugins/observability/e2e/synthetics_run.ts index f6ac3aaa49fda..f873c898aa45d 100644 --- a/x-pack/plugins/observability/e2e/synthetics_run.ts +++ b/x-pack/plugins/observability/e2e/synthetics_run.ts @@ -25,9 +25,14 @@ async function runE2ETests({ readConfigFile }: FtrConfigProviderContext) { await syntheticsRunner.setup(); - const fixturesDir = path.join(__dirname, '../../ux/e2e/fixtures/'); - - await syntheticsRunner.loadTestData(fixturesDir, ['rum_8.0.0', 'rum_test_data']); + await syntheticsRunner.loadTestData(path.join(__dirname, '../../ux/e2e/fixtures/'), [ + 'rum_8.0.0', + 'rum_test_data', + ]); + await syntheticsRunner.loadTestData( + path.join(__dirname, '../../synthetics/e2e/fixtures/es_archiver/'), + ['full_heartbeat', 'browser'] + ); await syntheticsRunner.loadTestFiles(async () => { require('./journeys'); }); diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.ts index fab9681bcf0c3..daf03d8fb33ef 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.ts @@ -584,6 +584,7 @@ export class LensAttributes { getFieldMeta(sourceField: string, layerConfig: LayerConfig) { if (sourceField === REPORT_METRIC_FIELD) { const { + palette, fieldName, columnType, columnLabel, @@ -594,6 +595,7 @@ export class LensAttributes { } = parseCustomFieldName(layerConfig.seriesConfig, layerConfig.selectedMetricField); const fieldMeta = layerConfig.indexPattern.getFieldByName(fieldName!); return { + palette, fieldMeta, fieldName, columnType, @@ -891,40 +893,53 @@ export class LensAttributes { } getDataLayers(): XYState['layers'] { - const dataLayers = this.layerConfigs.map((layerConfig, index) => ({ - accessors: [ - `y-axis-column-layer${index}`, - ...Object.keys(this.getChildYAxises(layerConfig, `layer${index}`, undefined, true)), - ], - layerId: `layer${index}`, - layerType: 'data' as any, - seriesType: layerConfig.seriesType || layerConfig.seriesConfig.defaultSeriesType, - palette: layerConfig.seriesConfig.palette, - yConfig: layerConfig.seriesConfig.yConfig || [ - { - forAccessor: `y-axis-column-layer${index}`, - color: layerConfig.color, - /* if the fields format matches the field format of the first layer, use the default y axis (right) - * if not, use the secondary y axis (left) */ - axisMode: - layerConfig.indexPattern.fieldFormatMap[layerConfig.selectedMetricField]?.id === - this.layerConfigs[0].indexPattern.fieldFormatMap[ - this.layerConfigs[0].selectedMetricField - ]?.id - ? ('left' as YAxisMode) - : ('right' as YAxisMode), - }, - ], - xAccessor: `x-axis-column-layer${index}`, - ...(layerConfig.breakdown && - layerConfig.breakdown !== PERCENTILE && - layerConfig.seriesConfig.xAxisColumn.sourceField !== USE_BREAK_DOWN_COLUMN - ? { splitAccessor: `breakdown-column-layer${index}` } - : {}), - ...(this.layerConfigs[0].seriesConfig.yTitle - ? { yTitle: this.layerConfigs[0].seriesConfig.yTitle } - : {}), - })); + const dataLayers = this.layerConfigs.map((layerConfig, index) => { + const { sourceField } = layerConfig.seriesConfig.yAxisColumns[0]; + + let palette = layerConfig.seriesConfig.palette; + + if (sourceField) { + const fieldMeta = this.getFieldMeta(sourceField, layerConfig); + if (fieldMeta.palette) { + palette = fieldMeta.palette; + } + } + + return { + accessors: [ + `y-axis-column-layer${index}`, + ...Object.keys(this.getChildYAxises(layerConfig, `layer${index}`, undefined, true)), + ], + layerId: `layer${index}`, + layerType: 'data' as any, + seriesType: layerConfig.seriesType || layerConfig.seriesConfig.defaultSeriesType, + palette: palette ?? layerConfig.seriesConfig.palette, + yConfig: layerConfig.seriesConfig.yConfig || [ + { + forAccessor: `y-axis-column-layer${index}`, + color: layerConfig.color, + /* if the fields format matches the field format of the first layer, use the default y axis (right) + * if not, use the secondary y axis (left) */ + axisMode: + layerConfig.indexPattern.fieldFormatMap[layerConfig.selectedMetricField]?.id === + this.layerConfigs[0].indexPattern.fieldFormatMap[ + this.layerConfigs[0].selectedMetricField + ]?.id + ? ('left' as YAxisMode) + : ('right' as YAxisMode), + }, + ], + xAccessor: `x-axis-column-layer${index}`, + ...(layerConfig.breakdown && + layerConfig.breakdown !== PERCENTILE && + layerConfig.seriesConfig.xAxisColumn.sourceField !== USE_BREAK_DOWN_COLUMN + ? { splitAccessor: `breakdown-column-layer${index}` } + : {}), + ...(this.layerConfigs[0].seriesConfig.yTitle + ? { yTitle: this.layerConfigs[0].seriesConfig.yTitle } + : {}), + }; + }); const referenceLineLayers: XYState['layers'] = []; diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/synthetics/kpi_over_time_config.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/synthetics/kpi_over_time_config.ts index c626ba5d522c2..aff40f980f25f 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/synthetics/kpi_over_time_config.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/synthetics/kpi_over_time_config.ts @@ -75,7 +75,6 @@ export function getSyntheticsKPIConfig({ dataView }: ConfigProps): SeriesConfig PERCENTILE, ], baseFilters: [], - palette: { type: 'palette', name: 'status' }, definitionFields: [ { field: 'monitor.name', nested: SYNTHETICS_STEP_NAME, singleSelection: true }, { field: 'url.full', filters: buildExistsFilter('summary.up', dataView) }, @@ -92,12 +91,14 @@ export function getSyntheticsKPIConfig({ dataView }: ConfigProps): SeriesConfig id: SUMMARY_UP, label: UP_LABEL, columnType: OPERATION_COLUMN, + palette: { type: 'palette', name: 'status' }, }, { field: SUMMARY_DOWN, id: SUMMARY_DOWN, label: DOWN_LABEL, columnType: OPERATION_COLUMN, + palette: { type: 'palette', name: 'status' }, }, { label: STEP_DURATION_LABEL, diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/types.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/types.ts index 5632397584bb2..f369a65db704c 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/types.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/types.ts @@ -68,6 +68,7 @@ export interface MetricOption { showPercentileAnnotations?: boolean; formula?: string; metricStateOptions?: Pick; + palette?: PaletteOutput; } export interface SeriesConfig {