[TextBased] Add FTs in Discover (#161522)

## Summary

Part of https://github.com/elastic/kibana/issues/158802

This PR:
- Removes the SQL option from Lens dataview picker
- Adds FTs in Discover to test better the edit by Discover and edit by
dashboard flyouts

Flaky test runner
https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/2594

### Checklist

- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
This commit is contained in:
Stratoula Kalafateli 2023-07-10 17:57:58 +03:00 committed by GitHub
parent 6db79db1e0
commit 0be1d5b1c0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 63 additions and 250 deletions

View file

@ -18,8 +18,6 @@ export const NOT_INTERNATIONALIZED_PRODUCT_NAME = 'Lens Visualizations';
export const BASE_API_URL = '/api/lens';
export const LENS_EDIT_BY_VALUE = 'edit_by_value';
export const ENABLE_SQL = 'discover:enableSql';
export const PieChartTypes = {
PIE: 'pie',
DONUT: 'donut',

View file

@ -17,7 +17,7 @@ import { useKibana } from '@kbn/kibana-react-plugin/public';
import { DataViewPickerProps } from '@kbn/unified-search-plugin/public';
import moment from 'moment';
import { LENS_APP_LOCATOR } from '../../common/locator/locator';
import { ENABLE_SQL, LENS_APP_NAME } from '../../common/constants';
import { LENS_APP_NAME } from '../../common/constants';
import { LensAppServices, LensTopNavActions, LensTopNavMenuProps } from './types';
import { toggleSettingsMenuOpen } from './settings_menu';
import {
@ -986,13 +986,6 @@ export const LensTopNavMenu = ({
]
);
// setting that enables/disables SQL
const isSQLModeEnabled = uiSettings.get(ENABLE_SQL);
const supportedTextBasedLanguages = [];
if (isSQLModeEnabled) {
supportedTextBasedLanguages.push('SQL');
}
const dataViewPickerProps: DataViewPickerProps = {
trigger: {
label: currentIndexPattern?.getName?.() || '',
@ -1052,7 +1045,6 @@ export const LensTopNavMenu = ({
indexPatternService.replaceDataViewId(updatedDataViewStub);
}
},
textBasedLanguages: supportedTextBasedLanguages as DataViewPickerProps['textBasedLanguages'],
};
const textBasedLanguageModeErrors = getUserMessages('textBasedLanguagesQueryInput', {

View file

@ -6,6 +6,7 @@
*/
import expect from '@kbn/expect';
import { DebugState } from '@elastic/charts';
import { WebElementWrapper } from '../../../../../test/functional/services/lib/web_element_wrapper';
import { FtrProviderContext } from '../../ftr_provider_context';
@ -28,6 +29,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
'header',
'unifiedFieldList',
]);
const elasticChart = getService('elasticChart');
const monacoEditor = getService('monacoEditor');
const defaultSettings = {
@ -38,6 +40,16 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
await PageObjects.timePicker.setDefaultAbsoluteRange();
}
function assertMatchesExpectedData(state: DebugState) {
expect(state.legend?.items.map(({ name }) => name).sort()).to.eql([
'css',
'gif',
'jpg',
'php',
'png',
]);
}
describe('discover field visualize button', () => {
before(async () => {
await kibanaServer.uiSettings.replace(defaultSettings);
@ -147,7 +159,33 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
expect(await testSubjects.exists('partitionVisChart')).to.be(true);
});
it('should visualize correctly text based language queries in Lens', async () => {
it('should allow changing dimensions', async () => {
await elasticChart.setNewChartUiDebugFlag(true);
await PageObjects.discover.selectTextBaseLang('SQL');
await PageObjects.header.waitUntilLoadingHasFinished();
await monacoEditor.setCodeEditorValue(
'SELECT extension, AVG("bytes") as average FROM "logstash-*" GROUP BY extension'
);
await testSubjects.click('querySubmitButton');
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.chooseLensChart('Bar vertical stacked');
await PageObjects.header.waitUntilLoadingHasFinished();
await testSubjects.click('unifiedHistogramEditFlyoutVisualization');
expect(await testSubjects.exists('xyVisChart')).to.be(true);
expect(await PageObjects.lens.canRemoveDimension('lnsXY_xDimensionPanel')).to.equal(true);
await PageObjects.lens.removeDimension('lnsXY_xDimensionPanel');
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.lens.configureTextBasedLanguagesDimension({
dimension: 'lnsXY_splitDimensionPanel > lns-empty-dimension',
field: 'extension',
});
await PageObjects.header.waitUntilLoadingHasFinished();
const data = await PageObjects.lens.getCurrentChartDebugStateForVizType('xyVisChart');
assertMatchesExpectedData(data!);
});
it('should visualize correctly text based language queries in Lenss', async () => {
await PageObjects.discover.selectTextBaseLang('SQL');
await PageObjects.header.waitUntilLoadingHasFinished();
await monacoEditor.setCodeEditorValue(
@ -185,7 +223,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
});
});
it('should save correctly chart to dashboard', async () => {
it('should save and edit chart in the dashboard on the fly', async () => {
await PageObjects.discover.selectTextBaseLang('SQL');
await PageObjects.header.waitUntilLoadingHasFinished();
await monacoEditor.setCodeEditorValue(
@ -193,12 +231,28 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
);
await testSubjects.click('querySubmitButton');
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.chooseLensChart('Bar vertical stacked');
await testSubjects.click('TextBasedLangEditor-expand');
await testSubjects.click('unifiedHistogramSaveVisualization');
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.lens.saveModal('TextBasedChart', false, false, false, 'new');
await testSubjects.existOrFail('embeddablePanelHeading-TextBasedChart');
await elasticChart.setNewChartUiDebugFlag(true);
await PageObjects.header.waitUntilLoadingHasFinished();
await testSubjects.click('embeddablePanelToggleMenuIcon');
await testSubjects.click('embeddablePanelAction-ACTION_CONFIGURE_IN_LENS');
await PageObjects.header.waitUntilLoadingHasFinished();
expect(await PageObjects.lens.canRemoveDimension('lnsXY_xDimensionPanel')).to.equal(true);
await PageObjects.lens.removeDimension('lnsXY_xDimensionPanel');
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.lens.configureTextBasedLanguagesDimension({
dimension: 'lnsXY_splitDimensionPanel > lns-empty-dimension',
field: 'extension',
});
await PageObjects.header.waitUntilLoadingHasFinished();
const data = await PageObjects.lens.getCurrentChartDebugStateForVizType('xyVisChart');
assertMatchesExpectedData(data!);
});
});
}

View file

@ -59,7 +59,6 @@ export default ({ getService, loadTestFile, getPageObjects }: FtrProviderContext
loadTestFile(require.resolve('./persistent_context')); // 1m
loadTestFile(require.resolve('./table_dashboard')); // 3m 10s
loadTestFile(require.resolve('./table')); // 1m 40s
loadTestFile(require.resolve('./text_based_languages')); // 3m 40s
loadTestFile(require.resolve('./fields_list')); // 2m 7s
loadTestFile(require.resolve('./layer_actions')); // 1m 45s
loadTestFile(require.resolve('./field_formatters')); // 1m 30s

View file

@ -1,235 +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 { DebugState } from '@elastic/charts';
import expect from '@kbn/expect';
import { FtrProviderContext } from '../../../ftr_provider_context';
export default function ({ getService, getPageObjects }: FtrProviderContext) {
const PageObjects = getPageObjects([
'visualize',
'lens',
'header',
'unifiedSearch',
'dashboard',
'common',
]);
const browser = getService('browser');
const elasticChart = getService('elasticChart');
const queryBar = getService('queryBar');
const testSubjects = getService('testSubjects');
const kibanaServer = getService('kibanaServer');
const monacoEditor = getService('monacoEditor');
function assertMatchesExpectedData(state: DebugState) {
expect(state.axes?.x![0].labels.sort()).to.eql(['css', 'gif', 'jpg', 'php', 'png']);
}
const defaultSettings = {
'discover:enableSql': true,
defaultIndex: 'log*',
};
async function switchToTextBasedLanguage(language: string) {
await PageObjects.visualize.navigateToNewVisualization();
await PageObjects.visualize.clickVisType('lens');
await PageObjects.lens.goToTimeRange();
await elasticChart.setNewChartUiDebugFlag(true);
await PageObjects.lens.switchToTextBasedLanguage(language);
await PageObjects.header.waitUntilLoadingHasFinished();
}
describe('lens text based language tests', () => {
before(async () => {
await kibanaServer.uiSettings.update(defaultSettings);
});
it('should navigate to text based languages mode correctly', async () => {
await switchToTextBasedLanguage('SQL');
expect(await testSubjects.exists('showQueryBarMenu')).to.be(false);
expect(await testSubjects.exists('addFilter')).to.be(false);
await testSubjects.click('TextBasedLangEditor-expand');
const textBasedQuery = await monacoEditor.getCodeEditorValue();
expect(textBasedQuery).to.be('SELECT * FROM "log*"');
await testSubjects.click('TextBasedLangEditor-minimize');
});
it('should allow adding and using a field', async () => {
await monacoEditor.setCodeEditorValue(
'SELECT extension, AVG("bytes") as average FROM "logstash-*" GROUP BY extension'
);
await testSubjects.click('querySubmitButton');
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.lens.switchToVisualization('lnsMetric');
await PageObjects.lens.configureTextBasedLanguagesDimension({
dimension: 'lnsMetric_primaryMetricDimensionPanel > lns-empty-dimension',
field: 'average',
});
await PageObjects.lens.waitForVisualization('mtrVis');
const metricData = await PageObjects.lens.getMetricVisualizationData();
expect(metricData[0].title).to.eql('average');
});
it('should allow switching to another chart', async () => {
await testSubjects.click('querySubmitButton');
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.lens.switchToVisualization('bar');
await PageObjects.lens.configureTextBasedLanguagesDimension({
dimension: 'lnsXY_xDimensionPanel > lns-empty-dimension',
field: 'extension',
});
await PageObjects.lens.configureTextBasedLanguagesDimension({
dimension: 'lnsXY_yDimensionPanel > lns-empty-dimension',
field: 'average',
});
await PageObjects.lens.waitForVisualization('xyVisChart');
const data = await PageObjects.lens.getCurrentChartDebugState('xyVisChart');
assertMatchesExpectedData(data!);
});
it('should be possible to share a URL of a visualization with text-based language', async () => {
const url = await PageObjects.lens.getUrl('snapshot');
await browser.openNewTab();
const [lensWindowHandler] = await browser.getAllWindowHandles();
await browser.navigateTo(url);
// check that it's the same configuration in the new URL when ready
await PageObjects.header.waitUntilLoadingHasFinished();
expect(
await PageObjects.lens.getDimensionTriggerText('lnsXY_xDimensionPanel', 0, true)
).to.eql('extension');
expect(
await PageObjects.lens.getDimensionTriggerText('lnsXY_yDimensionPanel', 0, true)
).to.eql('average');
await browser.closeCurrentWindow();
await browser.switchToWindow(lensWindowHandler);
});
it('should be possible to download a visualization with text-based language', async () => {
await PageObjects.lens.setCSVDownloadDebugFlag(true);
await PageObjects.lens.openCSVDownloadShare();
const csv = await PageObjects.lens.getCSVContent();
expect(csv).to.be.ok();
expect(Object.keys(csv!)).to.have.length(1);
await PageObjects.lens.setCSVDownloadDebugFlag(false);
});
it('should allow adding an text based languages chart to a dashboard', async () => {
await PageObjects.lens.switchToVisualization('lnsMetric');
await PageObjects.lens.waitForVisualization('mtrVis');
await PageObjects.lens.removeDimension('lnsMetric_breakdownByDimensionPanel');
await PageObjects.lens.waitForVisualization('mtrVis');
const metricData = await PageObjects.lens.getMetricVisualizationData();
expect(metricData[0].value).to.eql('5,699.406');
expect(metricData[0].title).to.eql('average');
await PageObjects.lens.save('New text based languages viz', false, false, false, 'new');
await PageObjects.dashboard.waitForRenderComplete();
expect(metricData[0].value).to.eql('5,699.406');
const panelCount = await PageObjects.dashboard.getPanelCount();
expect(panelCount).to.eql(1);
});
it('should allow saving the text based languages chart into a saved object', async () => {
await switchToTextBasedLanguage('SQL');
await monacoEditor.setCodeEditorValue(
'SELECT extension, AVG("bytes") as average FROM "logstash-*" GROUP BY extension'
);
await testSubjects.click('querySubmitButton');
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.lens.configureTextBasedLanguagesDimension({
dimension: 'lnsXY_xDimensionPanel > lns-empty-dimension',
field: 'extension',
});
await PageObjects.lens.configureTextBasedLanguagesDimension({
dimension: 'lnsXY_yDimensionPanel > lns-empty-dimension',
field: 'average',
});
await PageObjects.lens.waitForVisualization('xyVisChart');
await PageObjects.lens.save('Lens with text based language');
await PageObjects.lens.waitForVisualization('xyVisChart');
const data = await PageObjects.lens.getCurrentChartDebugState('xyVisChart');
assertMatchesExpectedData(data!);
});
it('should allow to return to the dataview mode', async () => {
await PageObjects.lens.switchDataPanelIndexPattern('logstash-*', true);
expect(await testSubjects.exists('addFilter')).to.be(true);
expect(await queryBar.getQueryString()).to.be('');
});
it('should allow using an index pattern that is not translated to a dataview', async () => {
await switchToTextBasedLanguage('SQL');
await testSubjects.click('TextBasedLangEditor-expand');
await monacoEditor.setCodeEditorValue(
'SELECT extension, AVG("bytes") as average FROM "logstash*" GROUP BY extension'
);
await testSubjects.click('querySubmitButton');
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.lens.switchToVisualization('lnsMetric');
await PageObjects.lens.configureTextBasedLanguagesDimension({
dimension: 'lnsMetric_primaryMetricDimensionPanel > lns-empty-dimension',
field: 'average',
});
await PageObjects.lens.waitForVisualization('mtrVis');
const metricData = await PageObjects.lens.getMetricVisualizationData();
expect(metricData[0].title).to.eql('average');
});
it('should be possible to share a URL of a visualization with text-based language that points to an index pattern', async () => {
// TODO: there's some state leakage in Lens when passing from a XY chart to new Metric chart
// which generates a wrong state (even tho it looks to work, starting fresh with such state breaks the editor)
await PageObjects.lens.removeLayer();
await PageObjects.lens.switchToVisualization('bar');
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.lens.configureTextBasedLanguagesDimension({
dimension: 'lnsXY_xDimensionPanel > lns-empty-dimension',
field: 'extension',
});
await PageObjects.lens.configureTextBasedLanguagesDimension({
dimension: 'lnsXY_yDimensionPanel > lns-empty-dimension',
field: 'average',
});
const url = await PageObjects.lens.getUrl('snapshot');
await browser.openNewTab();
const [lensWindowHandler] = await browser.getAllWindowHandles();
await browser.navigateTo(url);
// check that it's the same configuration in the new URL when ready
await PageObjects.header.waitUntilLoadingHasFinished();
expect(
await PageObjects.lens.getDimensionTriggerText('lnsXY_xDimensionPanel', 0, true)
).to.eql('extension');
expect(
await PageObjects.lens.getDimensionTriggerText('lnsXY_yDimensionPanel', 0, true)
).to.eql('average');
await browser.closeCurrentWindow();
await browser.switchToWindow(lensWindowHandler);
});
it('should be possible to download a visualization with text-based language that points to an index pattern', async () => {
await PageObjects.lens.setCSVDownloadDebugFlag(true);
await PageObjects.lens.openCSVDownloadShare();
const csv = await PageObjects.lens.getCSVContent();
expect(csv).to.be.ok();
expect(Object.keys(csv!)).to.have.length(1);
await PageObjects.lens.setCSVDownloadDebugFlag(false);
});
});
}

View file

@ -1078,6 +1078,11 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont
return el.getVisibleText();
},
async getCurrentChartDebugStateForVizType(visType: string) {
await this.waitForVisualization(visType);
return await elasticChart.getChartDebugData(visType);
},
/**
* Gets text of the specified datatable cell
*
@ -1454,7 +1459,7 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont
}
if (!opts.keepOpen) {
await this.closeDimensionEditor();
await testSubjects.click('collapseFlyoutButton');
}
},