2020-01-07 15:42:20 +01:00
|
|
|
/*
|
2021-01-20 02:52:56 +01:00
|
|
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
|
|
* or more contributor license agreements. Licensed under the Elastic License
|
2021-02-04 03:12:39 +01:00
|
|
|
* 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.
|
2020-01-07 15:42:20 +01:00
|
|
|
*/
|
|
|
|
|
2020-12-18 15:38:07 +01:00
|
|
|
import { Position } from '@elastic/charts';
|
2021-10-12 16:36:18 +02:00
|
|
|
import chroma from 'chroma-js';
|
2020-12-18 15:38:07 +01:00
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
import { FtrService } from '../ftr_provider_context';
|
2020-01-07 15:42:20 +01:00
|
|
|
|
2021-06-03 17:17:14 +02:00
|
|
|
const pieChartSelector = 'visTypePieChart';
|
2020-12-18 15:38:07 +01:00
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
export class VisualizeChartPageObject extends FtrService {
|
|
|
|
private readonly testSubjects = this.ctx.getService('testSubjects');
|
|
|
|
private readonly config = this.ctx.getService('config');
|
|
|
|
private readonly find = this.ctx.getService('find');
|
|
|
|
private readonly log = this.ctx.getService('log');
|
|
|
|
private readonly retry = this.ctx.getService('retry');
|
|
|
|
private readonly kibanaServer = this.ctx.getService('kibanaServer');
|
|
|
|
private readonly elasticChart = this.ctx.getService('elasticChart');
|
|
|
|
private readonly dataGrid = this.ctx.getService('dataGrid');
|
|
|
|
private readonly common = this.ctx.getPageObject('common');
|
2021-09-29 08:55:54 +02:00
|
|
|
private readonly header = this.ctx.getPageObject('header');
|
2021-06-04 19:17:00 +02:00
|
|
|
|
|
|
|
private readonly defaultFindTimeout = this.config.get('timeouts.find');
|
|
|
|
|
|
|
|
public async getEsChartDebugState(chartSelector: string) {
|
|
|
|
return await this.elasticChart.getChartDebugData(chartSelector);
|
|
|
|
}
|
2020-12-18 15:38:07 +01:00
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
/**
|
|
|
|
* Is new charts library advanced setting enabled
|
|
|
|
*/
|
|
|
|
public async isNewChartsLibraryEnabled(): Promise<boolean> {
|
|
|
|
const legacyChartsLibrary =
|
|
|
|
Boolean(
|
2021-09-08 17:35:51 +02:00
|
|
|
await this.kibanaServer.uiSettings.get('visualization:visualize:legacyPieChartsLibrary')
|
2021-06-04 19:17:00 +02:00
|
|
|
) ?? true;
|
|
|
|
const enabled = !legacyChartsLibrary;
|
|
|
|
this.log.debug(`-- isNewChartsLibraryEnabled = ${enabled}`);
|
|
|
|
|
|
|
|
return enabled;
|
|
|
|
}
|
2020-12-18 15:38:07 +01:00
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
/**
|
|
|
|
* Is new charts library enabled and an area, line or histogram chart exists
|
|
|
|
*/
|
|
|
|
public async isNewLibraryChart(chartSelector: string): Promise<boolean> {
|
|
|
|
const enabled = await this.isNewChartsLibraryEnabled();
|
2020-12-18 15:38:07 +01:00
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
if (!enabled) {
|
|
|
|
this.log.debug(`-- isNewLibraryChart = false`);
|
|
|
|
return false;
|
|
|
|
}
|
2020-12-18 15:38:07 +01:00
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
// check if enabled but not a line, area, histogram or pie chart
|
|
|
|
if (await this.find.existsByCssSelector('.visLib__chart', 1)) {
|
|
|
|
const chart = await this.find.byCssSelector('.visLib__chart');
|
|
|
|
const chartType = await chart.getAttribute('data-vislib-chart-type');
|
2020-12-18 15:38:07 +01:00
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
if (!['line', 'area', 'histogram', 'pie'].includes(chartType)) {
|
|
|
|
this.log.debug(`-- isNewLibraryChart = false`);
|
2020-12-18 15:38:07 +01:00
|
|
|
return false;
|
|
|
|
}
|
2021-06-04 19:17:00 +02:00
|
|
|
}
|
2020-12-18 15:38:07 +01:00
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
if (!(await this.elasticChart.hasChart(chartSelector, 1))) {
|
|
|
|
// not be a vislib chart type
|
|
|
|
this.log.debug(`-- isNewLibraryChart = false`);
|
|
|
|
return false;
|
2020-12-18 15:38:07 +01:00
|
|
|
}
|
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
this.log.debug(`-- isNewLibraryChart = true`);
|
|
|
|
return true;
|
|
|
|
}
|
2020-12-18 15:38:07 +01:00
|
|
|
|
2021-09-08 17:35:51 +02:00
|
|
|
public async getYAxisTitle(selector: string) {
|
|
|
|
const xAxis = (await this.getEsChartDebugState(selector))?.axes?.y ?? [];
|
|
|
|
return xAxis[0]?.title;
|
2021-06-04 19:17:00 +02:00
|
|
|
}
|
2020-12-18 15:38:07 +01:00
|
|
|
|
2021-09-08 17:35:51 +02:00
|
|
|
public async getXAxisLabels(selector: string) {
|
|
|
|
const [xAxis] = (await this.getEsChartDebugState(selector))?.axes?.x ?? [];
|
|
|
|
return xAxis?.labels;
|
2021-06-04 19:17:00 +02:00
|
|
|
}
|
2020-12-18 15:38:07 +01:00
|
|
|
|
2021-09-08 17:35:51 +02:00
|
|
|
public async getYAxisLabels(selector: string, nth = 0) {
|
|
|
|
const yAxis = (await this.getEsChartDebugState(selector))?.axes?.y ?? [];
|
|
|
|
return yAxis[nth]?.labels;
|
2021-06-04 19:17:00 +02:00
|
|
|
}
|
2020-12-18 15:38:07 +01:00
|
|
|
|
2021-09-08 17:35:51 +02:00
|
|
|
public async getYAxisLabelsAsNumbers(selector: string) {
|
|
|
|
const [yAxis] = (await this.getEsChartDebugState(selector))?.axes?.y ?? [];
|
|
|
|
return yAxis?.values;
|
2021-06-04 19:17:00 +02:00
|
|
|
}
|
2020-01-07 15:42:20 +01:00
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
/**
|
|
|
|
* Gets the chart data and scales it based on chart height and label.
|
|
|
|
* @param dataLabel data-label value
|
2021-09-08 17:35:51 +02:00
|
|
|
* @param selector chart selector
|
2021-08-04 20:56:46 +02:00
|
|
|
* @param shouldContainXAxisData boolean value for mapping points, false by default
|
2021-06-04 19:17:00 +02:00
|
|
|
*
|
|
|
|
* Returns an array of height values
|
|
|
|
*/
|
2021-08-04 20:56:46 +02:00
|
|
|
public async getAreaChartData(
|
|
|
|
dataLabel: string,
|
2021-09-08 17:35:51 +02:00
|
|
|
selector: string,
|
2021-08-04 20:56:46 +02:00
|
|
|
shouldContainXAxisData = false
|
|
|
|
) {
|
2021-09-08 17:35:51 +02:00
|
|
|
const areas = (await this.getEsChartDebugState(selector))?.areas ?? [];
|
|
|
|
const points = areas.find(({ name }) => name === dataLabel)?.lines.y1.points ?? [];
|
|
|
|
return shouldContainXAxisData ? points.map(({ x, y }) => [x, y]) : points.map(({ y }) => y);
|
2021-06-04 19:17:00 +02:00
|
|
|
}
|
2020-01-07 15:42:20 +01:00
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
/**
|
|
|
|
* Returns the paths that compose an area chart.
|
|
|
|
* @param dataLabel data-label value
|
|
|
|
*/
|
2021-09-08 17:35:51 +02:00
|
|
|
public async getAreaChartPaths(dataLabel: string, selector: string) {
|
|
|
|
const areas = (await this.getEsChartDebugState(selector))?.areas ?? [];
|
|
|
|
const path = areas.find(({ name }) => name === dataLabel)?.path ?? '';
|
|
|
|
return path.split('L');
|
2021-06-04 19:17:00 +02:00
|
|
|
}
|
2020-01-07 15:42:20 +01:00
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
/**
|
|
|
|
* Gets the dots and normalizes their height.
|
|
|
|
* @param dataLabel data-label value
|
|
|
|
* @param axis axis value, 'ValueAxis-1' by default
|
|
|
|
*/
|
2021-09-08 17:35:51 +02:00
|
|
|
public async getLineChartData(selector: string, dataLabel = 'Count') {
|
|
|
|
// For now lines are rendered as areas to enable stacking
|
|
|
|
const areas = (await this.getEsChartDebugState(selector))?.areas ?? [];
|
|
|
|
const lines = areas.map(({ lines: { y1 }, name, color }) => ({ ...y1, name, color }));
|
|
|
|
const points = lines.find(({ name }) => name === dataLabel)?.points ?? [];
|
|
|
|
return points.map(({ y }) => y);
|
2021-06-04 19:17:00 +02:00
|
|
|
}
|
2020-12-18 15:38:07 +01:00
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
/**
|
|
|
|
* Returns bar chart data in pixels
|
|
|
|
* @param dataLabel data-label value
|
|
|
|
*/
|
2021-09-08 17:35:51 +02:00
|
|
|
public async getBarChartData(selector: string, dataLabel = 'Count') {
|
|
|
|
const bars = (await this.getEsChartDebugState(selector))?.bars ?? [];
|
|
|
|
const values = bars.find(({ name }) => name === dataLabel)?.bars ?? [];
|
|
|
|
return values.map(({ y }) => y);
|
2021-06-04 19:17:00 +02:00
|
|
|
}
|
2020-12-18 15:38:07 +01:00
|
|
|
|
2021-09-08 17:35:51 +02:00
|
|
|
private async toggleLegend(force = false) {
|
2021-06-04 19:17:00 +02:00
|
|
|
const isVisTypePieChart = await this.isNewLibraryChart(pieChartSelector);
|
2021-09-08 17:35:51 +02:00
|
|
|
const legendSelector = force || isVisTypePieChart ? '.echLegend' : '.visLegend';
|
2020-01-07 15:42:20 +01:00
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
await this.retry.try(async () => {
|
|
|
|
const isVisible = await this.find.existsByCssSelector(legendSelector);
|
2021-09-08 17:35:51 +02:00
|
|
|
if (!isVisible) {
|
2021-06-04 19:17:00 +02:00
|
|
|
await this.testSubjects.click('vislibToggleLegend');
|
2020-12-18 15:38:07 +01:00
|
|
|
}
|
2021-06-04 19:17:00 +02:00
|
|
|
});
|
|
|
|
}
|
2020-12-18 15:38:07 +01:00
|
|
|
|
2021-09-08 17:35:51 +02:00
|
|
|
public async filterLegend(name: string, force = false) {
|
|
|
|
await this.toggleLegend(force);
|
2021-06-04 19:17:00 +02:00
|
|
|
await this.testSubjects.click(`legend-${name}`);
|
|
|
|
const filterIn = await this.testSubjects.find(`legend-${name}-filterIn`);
|
|
|
|
await filterIn.click();
|
|
|
|
await this.waitForVisualizationRenderingStabilized();
|
|
|
|
}
|
2020-01-07 15:42:20 +01:00
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
public async doesLegendColorChoiceExist(color: string) {
|
|
|
|
return await this.testSubjects.exists(`visColorPickerColor-${color}`);
|
|
|
|
}
|
2020-01-07 15:42:20 +01:00
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
public async selectNewLegendColorChoice(color: string) {
|
|
|
|
await this.testSubjects.click(`visColorPickerColor-${color}`);
|
|
|
|
}
|
2020-12-18 15:38:07 +01:00
|
|
|
|
2021-09-08 17:35:51 +02:00
|
|
|
public async doesSelectedLegendColorExistForXY(color: string, selector: string) {
|
|
|
|
const items = (await this.getEsChartDebugState(selector))?.legend?.items ?? [];
|
|
|
|
return items.some(({ color: c }) => c === color);
|
|
|
|
}
|
2020-01-07 15:42:20 +01:00
|
|
|
|
2021-10-12 16:36:18 +02:00
|
|
|
public async doesSelectedLegendColorExistForPie(matchingColor: string) {
|
2021-06-04 19:17:00 +02:00
|
|
|
if (await this.isNewLibraryChart(pieChartSelector)) {
|
2021-10-12 16:36:18 +02:00
|
|
|
const hexMatchingColor = chroma(matchingColor).hex().toUpperCase();
|
2021-06-04 19:17:00 +02:00
|
|
|
const slices =
|
|
|
|
(await this.getEsChartDebugState(pieChartSelector))?.partition?.[0]?.partitions ?? [];
|
2021-10-12 16:36:18 +02:00
|
|
|
return slices.some(({ color }) => {
|
|
|
|
return hexMatchingColor === chroma(color).hex().toUpperCase();
|
2021-06-04 19:17:00 +02:00
|
|
|
});
|
2020-01-07 15:42:20 +01:00
|
|
|
}
|
|
|
|
|
2021-10-12 16:36:18 +02:00
|
|
|
return await this.testSubjects.exists(`legendSelectedColor-${matchingColor}`);
|
2021-06-04 19:17:00 +02:00
|
|
|
}
|
2020-01-07 15:42:20 +01:00
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
public async expectError() {
|
2021-09-08 17:35:51 +02:00
|
|
|
if (!this.isNewLibraryChart(pieChartSelector)) {
|
2021-06-04 19:17:00 +02:00
|
|
|
await this.testSubjects.existOrFail('vislibVisualizeError');
|
2020-01-07 15:42:20 +01:00
|
|
|
}
|
2021-06-04 19:17:00 +02:00
|
|
|
}
|
2020-01-07 15:42:20 +01:00
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
public async getVisualizationRenderingCount() {
|
|
|
|
const visualizationLoader = await this.testSubjects.find('visualizationLoader');
|
|
|
|
const renderingCount = await visualizationLoader.getAttribute('data-rendering-count');
|
|
|
|
return Number(renderingCount);
|
|
|
|
}
|
2020-01-07 15:42:20 +01:00
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
public async waitForRenderingCount(minimumCount = 1) {
|
|
|
|
await this.retry.waitFor(
|
|
|
|
`rendering count to be greater than or equal to [${minimumCount}]`,
|
|
|
|
async () => {
|
|
|
|
const currentRenderingCount = await this.getVisualizationRenderingCount();
|
|
|
|
this.log.debug(`-- currentRenderingCount=${currentRenderingCount}`);
|
|
|
|
this.log.debug(`-- expectedCount=${minimumCount}`);
|
|
|
|
return currentRenderingCount >= minimumCount;
|
2020-12-18 15:38:07 +01:00
|
|
|
}
|
2021-06-04 19:17:00 +02:00
|
|
|
);
|
|
|
|
}
|
2020-01-07 15:42:20 +01:00
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
public async waitForVisualizationRenderingStabilized() {
|
2021-09-29 08:55:54 +02:00
|
|
|
await this.header.waitUntilLoadingHasFinished();
|
2021-06-04 19:17:00 +02:00
|
|
|
// assuming rendering is done when data-rendering-count is constant within 1000 ms
|
|
|
|
await this.retry.waitFor('rendering count to stabilize', async () => {
|
|
|
|
const firstCount = await this.getVisualizationRenderingCount();
|
|
|
|
this.log.debug(`-- firstCount=${firstCount}`);
|
2020-01-07 15:42:20 +01:00
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
await this.common.sleep(2000);
|
2020-01-07 15:42:20 +01:00
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
const secondCount = await this.getVisualizationRenderingCount();
|
|
|
|
this.log.debug(`-- secondCount=${secondCount}`);
|
2020-01-07 15:42:20 +01:00
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
return firstCount === secondCount;
|
|
|
|
});
|
|
|
|
}
|
2020-01-07 15:42:20 +01:00
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
public async waitForVisualization() {
|
|
|
|
await this.waitForVisualizationRenderingStabilized();
|
2021-09-08 17:35:51 +02:00
|
|
|
}
|
2020-01-07 15:42:20 +01:00
|
|
|
|
2021-09-08 17:35:51 +02:00
|
|
|
public async getLegendEntriesXYCharts(selector: string) {
|
|
|
|
const items = (await this.getEsChartDebugState(selector))?.legend?.items ?? [];
|
|
|
|
return items.map(({ name }) => name);
|
2021-06-04 19:17:00 +02:00
|
|
|
}
|
2020-01-07 15:42:20 +01:00
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
public async getLegendEntries() {
|
|
|
|
const isVisTypePieChart = await this.isNewLibraryChart(pieChartSelector);
|
2020-01-07 15:42:20 +01:00
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
if (isVisTypePieChart) {
|
|
|
|
const slices =
|
|
|
|
(await this.getEsChartDebugState(pieChartSelector))?.partition?.[0]?.partitions ?? [];
|
|
|
|
return slices.map(({ name }) => name);
|
2020-01-07 15:42:20 +01:00
|
|
|
}
|
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
const legendEntries = await this.find.allByCssSelector(
|
|
|
|
'.visLegend__button',
|
|
|
|
this.defaultFindTimeout * 2
|
|
|
|
);
|
|
|
|
return await Promise.all(
|
|
|
|
legendEntries.map(async (chart) => await chart.getAttribute('data-label'))
|
|
|
|
);
|
|
|
|
}
|
2020-01-07 15:42:20 +01:00
|
|
|
|
2021-09-08 17:35:51 +02:00
|
|
|
public async openLegendOptionColorsForXY(name: string, chartSelector: string) {
|
|
|
|
await this.waitForVisualizationRenderingStabilized();
|
|
|
|
await this.retry.try(async () => {
|
|
|
|
const chart = await this.find.byCssSelector(chartSelector);
|
|
|
|
const legendItemColor = await chart.findByCssSelector(
|
|
|
|
`[data-ech-series-name="${name}"] .echLegendItem__color`
|
|
|
|
);
|
|
|
|
legendItemColor.click();
|
|
|
|
|
|
|
|
await this.waitForVisualizationRenderingStabilized();
|
|
|
|
// arbitrary color chosen, any available would do
|
|
|
|
const arbitraryColor = '#d36086';
|
|
|
|
const isOpen = await this.doesLegendColorChoiceExist(arbitraryColor);
|
|
|
|
if (!isOpen) {
|
|
|
|
throw new Error('legend color selector not open');
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
public async openLegendOptionColorsForPie(name: string, chartSelector: string) {
|
2021-06-04 19:17:00 +02:00
|
|
|
await this.waitForVisualizationRenderingStabilized();
|
|
|
|
await this.retry.try(async () => {
|
2021-09-08 17:35:51 +02:00
|
|
|
if (await this.isNewLibraryChart(pieChartSelector)) {
|
2021-06-04 19:17:00 +02:00
|
|
|
const chart = await this.find.byCssSelector(chartSelector);
|
|
|
|
const legendItemColor = await chart.findByCssSelector(
|
|
|
|
`[data-ech-series-name="${name}"] .echLegendItem__color`
|
2020-12-18 15:38:07 +01:00
|
|
|
);
|
2021-06-04 19:17:00 +02:00
|
|
|
legendItemColor.click();
|
|
|
|
} else {
|
|
|
|
// This click has been flaky in opening the legend, hence the this.retry. See
|
|
|
|
// https://github.com/elastic/kibana/issues/17468
|
|
|
|
await this.testSubjects.click(`legend-${name}`);
|
|
|
|
}
|
2020-12-18 15:38:07 +01:00
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
await this.waitForVisualizationRenderingStabilized();
|
|
|
|
// arbitrary color chosen, any available would do
|
2021-09-08 17:35:51 +02:00
|
|
|
const arbitraryColor = '#EF843C';
|
2021-06-04 19:17:00 +02:00
|
|
|
const isOpen = await this.doesLegendColorChoiceExist(arbitraryColor);
|
|
|
|
if (!isOpen) {
|
|
|
|
throw new Error('legend color selector not open');
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2020-01-07 15:42:20 +01:00
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
public async filterOnTableCell(columnIndex: number, rowIndex: number) {
|
|
|
|
await this.retry.try(async () => {
|
|
|
|
const cell = await this.dataGrid.getCellElement(rowIndex, columnIndex);
|
|
|
|
await cell.click();
|
|
|
|
const filterBtn = await this.testSubjects.findDescendant(
|
|
|
|
'tbvChartCell__filterForCellValue',
|
|
|
|
cell
|
|
|
|
);
|
|
|
|
await this.common.sleep(2000);
|
|
|
|
filterBtn.click();
|
|
|
|
});
|
|
|
|
}
|
2020-01-07 15:42:20 +01:00
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
public async getMarkdownText() {
|
|
|
|
const markdownContainer = await this.testSubjects.find('markdownBody');
|
|
|
|
return markdownContainer.getVisibleText();
|
|
|
|
}
|
2020-07-03 23:09:02 +02:00
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
public async getMarkdownBodyDescendentText(selector: string) {
|
|
|
|
const markdownContainer = await this.testSubjects.find('markdownBody');
|
|
|
|
const element = await this.find.descendantDisplayedByCssSelector(selector, markdownContainer);
|
|
|
|
return element.getVisibleText();
|
|
|
|
}
|
2020-01-07 15:42:20 +01:00
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
// Table visualization
|
2020-12-15 12:44:20 +01:00
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
public async getTableVisNoResult() {
|
|
|
|
return await this.testSubjects.find('tbvChartContainer>visNoResult');
|
|
|
|
}
|
2020-11-17 13:18:07 +01:00
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
/**
|
|
|
|
* This function returns the text displayed in the Table Vis header
|
|
|
|
*/
|
|
|
|
public async getTableVisHeader() {
|
|
|
|
return await this.testSubjects.getVisibleText('dataGridHeader');
|
|
|
|
}
|
2020-01-07 15:42:20 +01:00
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
public async getFieldLinkInVisTable(fieldName: string, rowIndex: number = 1) {
|
|
|
|
const headers = await this.dataGrid.getHeaders();
|
|
|
|
const fieldColumnIndex = headers.indexOf(fieldName);
|
|
|
|
const cell = await this.dataGrid.getCellElement(rowIndex, fieldColumnIndex + 1);
|
|
|
|
return await cell.findByTagName('a');
|
|
|
|
}
|
2020-01-07 15:42:20 +01:00
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
/**
|
|
|
|
* Function to retrieve data from within a table visualization.
|
|
|
|
*/
|
|
|
|
public async getTableVisContent({ stripEmptyRows = true } = {}) {
|
|
|
|
return await this.retry.try(async () => {
|
|
|
|
const container = await this.testSubjects.find('tbvChart');
|
|
|
|
const allTables = await this.testSubjects.findAllDescendant('dataGridWrapper', container);
|
2020-01-07 15:42:20 +01:00
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
if (allTables.length === 0) {
|
|
|
|
return [];
|
|
|
|
}
|
2020-01-07 15:42:20 +01:00
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
const allData = await Promise.all(
|
|
|
|
allTables.map(async (t) => {
|
|
|
|
let data = await this.dataGrid.getDataFromElement(t, 'tbvChartCellContent');
|
|
|
|
if (stripEmptyRows) {
|
|
|
|
data = data.filter(
|
|
|
|
(row) => row.length > 0 && row.some((cell) => cell.trim().length > 0)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
return data;
|
2020-01-07 15:42:20 +01:00
|
|
|
})
|
|
|
|
);
|
2020-05-05 18:08:25 +02:00
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
if (allTables.length === 1) {
|
|
|
|
// If there was only one table we return only the data for that table
|
|
|
|
// This prevents an unnecessary array around that single table, which
|
|
|
|
// is the case we have in most tests.
|
|
|
|
return allData[0];
|
2020-12-18 15:38:07 +01:00
|
|
|
}
|
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
return allData;
|
|
|
|
});
|
|
|
|
}
|
2020-12-15 09:04:01 +01:00
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
public async getMetric() {
|
|
|
|
const elements = await this.find.allByCssSelector(
|
|
|
|
'[data-test-subj="visualizationLoader"] .mtrVis__container'
|
|
|
|
);
|
|
|
|
const values = await Promise.all(
|
|
|
|
elements.map(async (element) => {
|
|
|
|
const text = await element.getVisibleText();
|
|
|
|
return text;
|
|
|
|
})
|
|
|
|
);
|
|
|
|
return values
|
|
|
|
.filter((item) => item.length > 0)
|
|
|
|
.reduce((arr: string[], item) => arr.concat(item.split('\n')), []);
|
|
|
|
}
|
2020-12-15 09:04:01 +01:00
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
public async getGaugeValue() {
|
|
|
|
const elements = await this.find.allByCssSelector(
|
|
|
|
'[data-test-subj="visualizationLoader"] .chart svg text'
|
|
|
|
);
|
|
|
|
const values = await Promise.all(
|
|
|
|
elements.map(async (element) => {
|
|
|
|
const text = await element.getVisibleText();
|
|
|
|
return text;
|
|
|
|
})
|
|
|
|
);
|
|
|
|
return values.filter((item) => item.length > 0);
|
|
|
|
}
|
2020-05-05 18:08:25 +02:00
|
|
|
|
2021-09-08 17:35:51 +02:00
|
|
|
public async getAxesCountByPosition(
|
|
|
|
axesPosition: typeof Position[keyof typeof Position],
|
|
|
|
selector: string
|
|
|
|
) {
|
|
|
|
const yAxes = (await this.getEsChartDebugState(selector))?.axes?.y ?? [];
|
|
|
|
return yAxes.filter(({ position }) => position === axesPosition).length;
|
2021-06-04 19:17:00 +02:00
|
|
|
}
|
2020-05-05 18:08:25 +02:00
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
public async clickOnGaugeByLabel(label: string) {
|
|
|
|
const gauge = await this.testSubjects.find(`visGauge__meter--${label}`);
|
|
|
|
const gaugeSize = await gauge.getSize();
|
|
|
|
const gaugeHeight = gaugeSize.height;
|
|
|
|
// To click at Gauge arc instead of the center of SVG element
|
|
|
|
// the offset for a click is calculated as half arc height without 1 pixel
|
|
|
|
const yOffset = 1 - Math.floor(gaugeHeight / 2);
|
2020-12-18 15:38:07 +01:00
|
|
|
|
2021-06-04 19:17:00 +02:00
|
|
|
await gauge.clickMouseButton({ xOffset: 0, yOffset });
|
|
|
|
}
|
|
|
|
|
2021-09-08 17:35:51 +02:00
|
|
|
public async getAreaSeriesCount(selector: string) {
|
|
|
|
const areas = (await this.getEsChartDebugState(selector))?.areas ?? [];
|
|
|
|
return areas.filter((area) => area.lines.y1.visible).length;
|
2021-08-04 20:56:46 +02:00
|
|
|
}
|
|
|
|
|
2021-09-08 17:35:51 +02:00
|
|
|
public async getHistogramSeriesCount(selector: string) {
|
|
|
|
const bars = (await this.getEsChartDebugState(selector))?.bars ?? [];
|
|
|
|
return bars.filter(({ visible }) => visible).length;
|
2021-06-04 19:17:00 +02:00
|
|
|
}
|
2020-12-18 15:38:07 +01:00
|
|
|
|
2021-09-08 17:35:51 +02:00
|
|
|
public async getGridLines(selector: string): Promise<Array<{ x: number; y: number }>> {
|
|
|
|
const { x, y } = (await this.getEsChartDebugState(selector))?.axes ?? {
|
|
|
|
x: [],
|
|
|
|
y: [],
|
|
|
|
};
|
|
|
|
return [...x, ...y].flatMap(({ gridlines }) => gridlines);
|
2020-01-07 15:42:20 +01:00
|
|
|
}
|
|
|
|
|
2021-09-08 17:35:51 +02:00
|
|
|
public async getChartValues(selector: string) {
|
|
|
|
const barSeries = (await this.getEsChartDebugState(selector))?.bars ?? [];
|
|
|
|
return barSeries.filter(({ visible }) => visible).flatMap((bars) => bars.labels);
|
2021-06-04 19:17:00 +02:00
|
|
|
}
|
2020-01-07 15:42:20 +01:00
|
|
|
}
|