From 6174c1a2e7e97698587c3c01e385282f4f4afca2 Mon Sep 17 00:00:00 2001 From: Justin Kim Date: Tue, 28 Jan 2025 10:42:21 -0800 Subject: [PATCH 1/4] add tests for saved searches in dashboard: TESTID-116, TESTID-115, TESTID-61 Signed-off-by: Justin Kim --- .../saved_search_in_dashboards.spec.js | 154 ++++++++++++++++++ .../utils/apps/query_enhancements/saved.js | 30 ++++ 2 files changed, 184 insertions(+) create mode 100644 cypress/integration/core_opensearch_dashboards/opensearch_dashboards/apps/query_enhancements/saved_search_in_dashboards.spec.js diff --git a/cypress/integration/core_opensearch_dashboards/opensearch_dashboards/apps/query_enhancements/saved_search_in_dashboards.spec.js b/cypress/integration/core_opensearch_dashboards/opensearch_dashboards/apps/query_enhancements/saved_search_in_dashboards.spec.js new file mode 100644 index 00000000000..a81828e554e --- /dev/null +++ b/cypress/integration/core_opensearch_dashboards/opensearch_dashboards/apps/query_enhancements/saved_search_in_dashboards.spec.js @@ -0,0 +1,154 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { + DatasetTypes, + INDEX_PATTERN_WITH_TIME, + INDEX_WITH_TIME_1, + INDEX_WITH_TIME_2, + QueryLanguages, + SECONDARY_ENGINE, +} from '../../../../../utils/constants'; +import { + getRandomizedWorkspaceName, + getRandomizedDatasourceName, + setDatePickerDatesAndSearchIfRelevant, +} from '../../../../../utils/apps/query_enhancements/shared'; +import { + postRequestSaveSearch, + generateSavedTestConfiguration, + getExpectedHitCount, + loadSavedSearchFromDashboards, + navigateToDashboardAndOpenSavedSearchPanel, +} from '../../../../../utils/apps/query_enhancements/saved'; + +const workspaceName = getRandomizedWorkspaceName(); +const datasourceName = getRandomizedDatasourceName(); + +export const runSavedSearchTests = () => { + describe('saved search in dashboards', () => { + beforeEach(() => { + // Load test data + cy.setupTestData( + SECONDARY_ENGINE.url, + [ + `cypress/fixtures/query_enhancements/data_logs_1/${INDEX_WITH_TIME_1}.mapping.json`, + `cypress/fixtures/query_enhancements/data_logs_2/${INDEX_WITH_TIME_2}.mapping.json`, + ], + [ + `cypress/fixtures/query_enhancements/data_logs_1/${INDEX_WITH_TIME_1}.data.ndjson`, + `cypress/fixtures/query_enhancements/data_logs_2/${INDEX_WITH_TIME_2}.data.ndjson`, + ] + ); + // Add data source + cy.addDataSource({ + name: datasourceName, + url: SECONDARY_ENGINE.url, + authType: 'no_auth', + }); + + // Create workspace + cy.deleteWorkspaceByName(workspaceName); + cy.visit('/app/home'); + cy.osd.createInitialWorkspaceWithDataSource(datasourceName, workspaceName); + cy.createWorkspaceIndexPatterns({ + workspaceName: workspaceName, + indexPattern: INDEX_PATTERN_WITH_TIME.replace('*', ''), + timefieldName: 'timestamp', + dataSource: datasourceName, + isEnhancement: true, + }); + }); + + afterEach(() => { + cy.deleteWorkspaceByName(workspaceName); + // // TODO: Modify deleteIndex to handle an array of index and remove hard code + cy.deleteDataSourceByName(datasourceName); + cy.deleteIndex(INDEX_WITH_TIME_1); + cy.deleteIndex(INDEX_WITH_TIME_2); + }); + + it('Load a saved search', () => { + const config = generateSavedTestConfiguration( + INDEX_PATTERN_WITH_TIME, + DatasetTypes.INDEX_PATTERN.name, + QueryLanguages.DQL + ); + // using a POST request to create a saved search to load + postRequestSaveSearch(config); + + loadSavedSearchFromDashboards(config, workspaceName); + + // verify that there are results + cy.getElementByTestId('docTableField').should('be.visible'); + + const expectedHitCount = getExpectedHitCount(config.datasetType, config.language); + cy.getElementByTestId('osdDocTablePagination').contains(new RegExp(`of ${expectedHitCount}`)); + // verify that the proper fields are loaded as well as sorting is working as expected + config.sampleTableData.forEach(([index, value]) => { + cy.getElementByTestId('osdDocTableCellDataField').eq(index).contains(value); + }); + }); + + it('Changing the time range updates the saved search elements in dashboards', () => { + const config = generateSavedTestConfiguration( + INDEX_PATTERN_WITH_TIME, + DatasetTypes.INDEX_PATTERN.name, + QueryLanguages.DQL + ); + // using a POST request to create a saved search to load + postRequestSaveSearch(config); + + loadSavedSearchFromDashboards(config, workspaceName); + + // verify that there are results + cy.getElementByTestId('docTableField').should('be.visible'); + + // set a date where there should be no results + setDatePickerDatesAndSearchIfRelevant( + config.language, + 'Jan 1, 2024 @ 00:00:00.000', + 'Jan 2, 2024 @ 00:00:00.000' + ); + cy.get('p').contains('No results found').should('be.visible'); + }); + + it('Show valid saved searches', () => { + const dqlConfig = generateSavedTestConfiguration( + INDEX_PATTERN_WITH_TIME, + DatasetTypes.INDEX_PATTERN.name, + QueryLanguages.DQL + ); + const luceneConfig = generateSavedTestConfiguration( + INDEX_PATTERN_WITH_TIME, + DatasetTypes.INDEX_PATTERN.name, + QueryLanguages.Lucene + ); + const sqlConfig = generateSavedTestConfiguration( + INDEX_PATTERN_WITH_TIME, + DatasetTypes.INDEX_PATTERN.name, + QueryLanguages.SQL + ); + const pplConfig = generateSavedTestConfiguration( + INDEX_PATTERN_WITH_TIME, + DatasetTypes.INDEX_PATTERN.name, + QueryLanguages.PPL + ); + // using a POST request to create a saved search to load + postRequestSaveSearch(dqlConfig); + postRequestSaveSearch(luceneConfig); + postRequestSaveSearch(sqlConfig); + postRequestSaveSearch(pplConfig); + + navigateToDashboardAndOpenSavedSearchPanel(workspaceName); + cy.getElementByTestId(`savedObjectTitle${dqlConfig.saveName}`).should('exist'); + cy.getElementByTestId(`savedObjectTitle${luceneConfig.saveName}`).should('exist'); + cy.getElementByTestId(`savedObjectTitle${sqlConfig.saveName}`).should('not.exist'); + cy.getElementByTestId(`savedObjectTitle${pplConfig.saveName}`).should('not.exist'); + }); + }); +}; + +runSavedSearchTests(); diff --git a/cypress/utils/apps/query_enhancements/saved.js b/cypress/utils/apps/query_enhancements/saved.js index 7fd4d9bcd57..2ba3b14974d 100644 --- a/cypress/utils/apps/query_enhancements/saved.js +++ b/cypress/utils/apps/query_enhancements/saved.js @@ -496,3 +496,33 @@ export const updateSavedSearchAndSaveAndVerify = ( setDatePickerDatesAndSearchIfRelevant(newConfig.language); verifyDiscoverPageState(newConfig); }; + +/** + * Navigates to dashboard page, clicks new dashboard, and open up the saved search panel + * @param {string} workspaceName - name of workspace + */ +export const navigateToDashboardAndOpenSavedSearchPanel = (workspaceName) => { + cy.navigateToWorkSpaceSpecificPage({ + workspaceName, + page: 'dashboards', + isEnhancement: true, + }); + cy.getElementByTestId('newItemButton').click(); + // using DQL as it supports date picker + setDatePickerDatesAndSearchIfRelevant(QueryLanguages.DQL.name); + cy.getElementByTestId('dashboardAddPanelButton').click(); + cy.getElementByTestId('savedObjectFinderFilterButton').click(); + cy.getElementByTestId('savedObjectFinderFilter-search').click(); +}; + +/** + * Navigates to dashboard page and loads a saved search as a new dashboard + * @param {SavedTestConfig} config - the relevant config for the test case + * @param {string} workspaceName - name of workspace + */ +export const loadSavedSearchFromDashboards = (config, workspaceName) => { + navigateToDashboardAndOpenSavedSearchPanel(workspaceName); + cy.getElementByTestId(`savedObjectTitle${config.saveName}`).click(); + cy.getElementByTestId('addObjectToContainerSuccess').should('be.visible'); + cy.getElementByTestId('euiFlyoutCloseButton').click(); +}; From 69d2f807f1b53f3f133bc56216774993bc00e897 Mon Sep 17 00:00:00 2001 From: "opensearch-changeset-bot[bot]" <154024398+opensearch-changeset-bot[bot]@users.noreply.github.com> Date: Tue, 28 Jan 2025 18:46:51 +0000 Subject: [PATCH 2/4] Changeset file for PR #9288 created/updated --- changelogs/fragments/9288.yml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 changelogs/fragments/9288.yml diff --git a/changelogs/fragments/9288.yml b/changelogs/fragments/9288.yml new file mode 100644 index 00000000000..2804ab4d286 --- /dev/null +++ b/changelogs/fragments/9288.yml @@ -0,0 +1,2 @@ +test: +- Add tests for saved searches in dashboards ([#9288](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/9288)) \ No newline at end of file From 7771a7b964a1719a2d82a31965d3225e3bcdab5f Mon Sep 17 00:00:00 2001 From: Justin Kim Date: Tue, 28 Jan 2025 11:29:45 -0800 Subject: [PATCH 3/4] update test case to change date to where we have some results Signed-off-by: Justin Kim --- .../saved_search_in_dashboards.spec.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/cypress/integration/core_opensearch_dashboards/opensearch_dashboards/apps/query_enhancements/saved_search_in_dashboards.spec.js b/cypress/integration/core_opensearch_dashboards/opensearch_dashboards/apps/query_enhancements/saved_search_in_dashboards.spec.js index a81828e554e..a4f3bb38bb6 100644 --- a/cypress/integration/core_opensearch_dashboards/opensearch_dashboards/apps/query_enhancements/saved_search_in_dashboards.spec.js +++ b/cypress/integration/core_opensearch_dashboards/opensearch_dashboards/apps/query_enhancements/saved_search_in_dashboards.spec.js @@ -10,6 +10,7 @@ import { INDEX_WITH_TIME_2, QueryLanguages, SECONDARY_ENGINE, + START_TIME, } from '../../../../../utils/constants'; import { getRandomizedWorkspaceName, @@ -104,15 +105,16 @@ export const runSavedSearchTests = () => { loadSavedSearchFromDashboards(config, workspaceName); // verify that there are results - cy.getElementByTestId('docTableField').should('be.visible'); + const expectedHitCount = getExpectedHitCount(config.datasetType, config.language); + cy.getElementByTestId('osdDocTablePagination').contains(new RegExp(`of ${expectedHitCount}`)); - // set a date where there should be no results + // set a date where there should different number of results setDatePickerDatesAndSearchIfRelevant( config.language, - 'Jan 1, 2024 @ 00:00:00.000', - 'Jan 2, 2024 @ 00:00:00.000' + START_TIME, + 'Oct 1, 2022 @ 00:00:00.000' ); - cy.get('p').contains('No results found').should('be.visible'); + cy.getElementByTestId('osdDocTablePagination').contains(/of 15/); }); it('Show valid saved searches', () => { From 359589342c532213f24a50d196d2e6cb8d836ac1 Mon Sep 17 00:00:00 2001 From: Justin Kim Date: Wed, 29 Jan 2025 17:59:24 -0800 Subject: [PATCH 4/4] add to ci group 12 Signed-off-by: Justin Kim --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c4bcd799db2..cc97d73019d 100644 --- a/package.json +++ b/package.json @@ -88,7 +88,7 @@ "cypress:run-with-security": "env TZ=America/Los_Angeles NO_COLOR=1 cypress run --env SECURITY_ENABLED=true,openSearchUrl=https://localhost:9200,WAIT_FOR_LOADER_BUFFER_MS=500", "osd:ciGroup10": "BASE_PATH='cypress/integration/core_opensearch_dashboards/opensearch_dashboards/apps/query_enhancements' && echo \"$BASE_PATH/saved_search.spec.js,$BASE_PATH/queries.spec.js,$BASE_PATH/a_check.spec.js,$BASE_PATH/dataset_selector.spec.js,$BASE_PATH/s3_dataset.spec.js,$BASE_PATH/simple_dataset_selector.spec.js\"", "osd:ciGroup11": "echo \"cypress/integration/dashboard_sanity_test.spec.ts\"", - "osd:ciGroup12": "BASE_PATH='cypress/integration/core_opensearch_dashboards/opensearch_dashboards/apps/query_enhancements' && echo \"$BASE_PATH/time_range_selection.spec.js,$BASE_PATH/saved_queries.spec.js,$BASE_PATH/language_specific_display.spec.js,$BASE_PATH/field_display_filtering.spec.js\"", + "osd:ciGroup12": "BASE_PATH='cypress/integration/core_opensearch_dashboards/opensearch_dashboards/apps/query_enhancements' && echo \"$BASE_PATH/time_range_selection.spec.js,$BASE_PATH/saved_queries.spec.js,$BASE_PATH/language_specific_display.spec.js,$BASE_PATH/field_display_filtering.spec.js,$BASE_PATH/saved_search_in_dashboards.spec.js\"", "generate:opensearchsqlantlr": "./node_modules/antlr4ng-cli/index.js -Dlanguage=TypeScript -o ./src/plugins/data/public/antlr/opensearch_sql/.generated -visitor -no-listener -Xexact-output-dir ./src/plugins/data/public/antlr/opensearch_sql/grammar/OpenSearchSQLLexer.g4 ./src/plugins/data/public/antlr/opensearch_sql/grammar/OpenSearchSQLParser.g4", "generate:opensearchpplantlr": "./node_modules/antlr4ng-cli/index.js -Dlanguage=TypeScript -o ./src/plugins/data/public/antlr/opensearch_ppl/.generated -visitor -no-listener -Xexact-output-dir ./src/plugins/data/public/antlr/opensearch_ppl/grammar/OpenSearchPPLLexer.g4 ./src/plugins/data/public/antlr/opensearch_ppl/grammar/OpenSearchPPLParser.g4" },