From a162bdae646759c99f582a227316993255c7d336 Mon Sep 17 00:00:00 2001 From: Matthias Wilhelm Date: Wed, 6 Nov 2024 19:13:33 +0100 Subject: [PATCH] [Discover] Fix loading data views in ES|QL mode (#199099) - Closes https://github.com/elastic/kibana/issues/199065 ## Summary This PR makes sure that data views are loaded so user can view them after switching from ES|QL mode to data view mode. Looks like it was introduced in https://github.com/elastic/kibana/pull/195670 ### Testing On your local instance having `kibana_sample_data_logs` installed * Open a link to an ES|QL query [link](http://localhost:5601/xot/app/discover#/?_g=(filters:!(),refreshInterval:(pause:!t,value:60000),time:(from:now-15m,to:now))&_a=(columns:!(),dataSource:(dataViewId:e3465e67bdeced2befff9f9dca7ecf9c48504cad68a10efd881f4c7dd5ade28a,type:dataView),filters:!(),interval:auto,query:(language:kuery,query:''),sort:!(!(timestamp,desc)))) * Switch to classic * Open the DataView Picker, to see a list of DataViews, before this fix there were none ### 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 --------- Co-authored-by: Julia Rechkunova Co-authored-by: Julia Rechkunova (cherry picked from commit 08b83c55f64bc250a4b6d5909cfc2e46003e9751) --- .../application/main/discover_main_route.tsx | 10 ++--- .../apps/discover/esql/_esql_view.ts | 37 +++++++++++++++---- .../page_objects/unified_search_page.ts | 28 ++++++++++++++ .../common/discover/esql/_esql_view.ts | 20 ++++++++++ 4 files changed, 80 insertions(+), 15 deletions(-) diff --git a/src/plugins/discover/public/application/main/discover_main_route.tsx b/src/plugins/discover/public/application/main/discover_main_route.tsx index d86788172386f..205926cf4943b 100644 --- a/src/plugins/discover/public/application/main/discover_main_route.tsx +++ b/src/plugins/discover/public/application/main/discover_main_route.tsx @@ -120,14 +120,10 @@ export function DiscoverMainRoute({ const { dataSource } = stateContainer.appState.getState(); const isEsqlQuery = isDataSourceType(dataSource, DataSourceType.Esql); - // ES|QL should work without data views - // Given we have a saved search id, we can skip the data/data view check, too - // A given nextDataView is provided by the user, and therefore we can skip the data/data view check - if (savedSearchId || isEsqlQuery || nextDataView) { - if (!isEsqlQuery) { - await stateContainer.actions.loadDataViewList(); - } + // Although ES|QL doesn't need a data view, we still need to load the data view list to + // ensure the data view is available for the user to switch to classic mode + await stateContainer.actions.loadDataViewList(); return true; } diff --git a/test/functional/apps/discover/esql/_esql_view.ts b/test/functional/apps/discover/esql/_esql_view.ts index dc550ac5be93d..272de320d2051 100644 --- a/test/functional/apps/discover/esql/_esql_view.ts +++ b/test/functional/apps/discover/esql/_esql_view.ts @@ -25,14 +25,17 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const find = getService('find'); const esql = getService('esql'); const dashboardAddPanel = getService('dashboardAddPanel'); - const { common, discover, dashboard, header, timePicker, unifiedFieldList } = getPageObjects([ - 'common', - 'discover', - 'dashboard', - 'header', - 'timePicker', - 'unifiedFieldList', - ]); + const dataViews = getService('dataViews'); + const { common, discover, dashboard, header, timePicker, unifiedFieldList, unifiedSearch } = + getPageObjects([ + 'common', + 'discover', + 'dashboard', + 'header', + 'timePicker', + 'unifiedFieldList', + 'unifiedSearch', + ]); const defaultSettings = { defaultIndex: 'logstash-*', @@ -305,6 +308,24 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await testSubjects.existOrFail('discover-esql-to-dataview-modal'); }); }); + + it('should show available data views after switching to classic mode', async () => { + await discover.selectTextBaseLang(); + await header.waitUntilLoadingHasFinished(); + await discover.waitUntilSearchingHasFinished(); + + await browser.refresh(); + await header.waitUntilLoadingHasFinished(); + await discover.waitUntilSearchingHasFinished(); + await unifiedSearch.switchToDataViewMode(); + await header.waitUntilLoadingHasFinished(); + await discover.waitUntilSearchingHasFinished(); + const availableDataViews = await unifiedSearch.getDataViewList( + 'discover-dataView-switch-link' + ); + expect(availableDataViews).to.eql(['kibana_sample_data_flights', 'logstash-*']); + await dataViews.switchToAndValidate('kibana_sample_data_flights'); + }); }); describe('inspector', () => { diff --git a/test/functional/page_objects/unified_search_page.ts b/test/functional/page_objects/unified_search_page.ts index 0ccfb388f1f15..4c9c9e5f4976b 100644 --- a/test/functional/page_objects/unified_search_page.ts +++ b/test/functional/page_objects/unified_search_page.ts @@ -27,6 +27,28 @@ export class UnifiedSearchPageObject extends FtrService { ); } + public async getDataViewList(switchButtonSelector: string) { + await this.testSubjects.click(switchButtonSelector); + + await this.retry.waitFor( + 'wait for popover', + async () => await this.testSubjects.exists('indexPattern-switcher') + ); + + const indexPatternSwitcher = await this.testSubjects.find('indexPattern-switcher', 500); + const availableDataViews = await Promise.all( + ( + await indexPatternSwitcher.findAllByCssSelector('.euiSelectableListItem') + ).map(async (item) => { + return await item.getAttribute('title'); + }) + ); + + await this.testSubjects.click(switchButtonSelector); + + return availableDataViews; + } + public async getSelectedDataView(switchButtonSelector: string) { let visibleText = ''; @@ -46,6 +68,12 @@ export class UnifiedSearchPageObject extends FtrService { public async switchToDataViewMode() { await this.testSubjects.click('switch-to-dataviews'); + await this.retry.waitFor('the modal to open', async () => { + return await this.testSubjects.exists('discover-esql-to-dataview-modal'); + }); await this.testSubjects.click('discover-esql-to-dataview-no-save-btn'); + await this.retry.waitFor('the modal to close', async () => { + return !(await this.testSubjects.exists('discover-esql-to-dataview-modal')); + }); } } diff --git a/x-pack/test_serverless/functional/test_suites/common/discover/esql/_esql_view.ts b/x-pack/test_serverless/functional/test_suites/common/discover/esql/_esql_view.ts index c82882623b177..0df0676c1f246 100644 --- a/x-pack/test_serverless/functional/test_suites/common/discover/esql/_esql_view.ts +++ b/x-pack/test_serverless/functional/test_suites/common/discover/esql/_esql_view.ts @@ -21,6 +21,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const find = getService('find'); const esql = getService('esql'); const dashboardAddPanel = getService('dashboardAddPanel'); + const dataViews = getService('dataViews'); const PageObjects = getPageObjects([ 'svlCommonPage', 'common', @@ -29,6 +30,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { 'header', 'timePicker', 'unifiedFieldList', + 'unifiedSearch', ]); const defaultSettings = { @@ -311,6 +313,24 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await testSubjects.existOrFail('discover-esql-to-dataview-modal'); }); }); + + it('should show available data views after switching to classic mode', async () => { + await PageObjects.discover.selectTextBaseLang(); + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.discover.waitUntilSearchingHasFinished(); + + await browser.refresh(); + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.discover.waitUntilSearchingHasFinished(); + await PageObjects.unifiedSearch.switchToDataViewMode(); + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.discover.waitUntilSearchingHasFinished(); + const availableDataViews = await PageObjects.unifiedSearch.getDataViewList( + 'discover-dataView-switch-link' + ); + expect(availableDataViews).to.eql(['kibana_sample_data_flights', 'logstash-*']); + await dataViews.switchToAndValidate('kibana_sample_data_flights'); + }); }); describe('inspector', () => {