From 1dfcd345aef6692a07b1b09d392be2ee5b4e11ab Mon Sep 17 00:00:00 2001 From: Anan Date: Sun, 5 Jan 2025 23:16:35 -0800 Subject: [PATCH] Refactor TESTID 140 and clean up * Refactor this PR https://github.com/opensearch-project/OpenSearch-Dashboards/pull/9128 * Clean up structures Signed-off-by: Anan --- .../field_display_filtering.spec.js | 29 +- .../query_enhancements/helpers/commons.js | 75 +++++ .../field_display_filtering.js | 0 .../{utils => helpers}/saved_search.js | 63 +---- .../helpers/sidebar_filtering.js | 76 +++++ .../query_enhancements/saved_search.spec.js | 4 +- .../sidebar_filtering.spec.js | 265 ++++++++++++++++++ 7 files changed, 435 insertions(+), 77 deletions(-) create mode 100644 cypress/integration/core-opensearch-dashboards/opensearch-dashboards/apps/query_enhancements/helpers/commons.js rename cypress/integration/core-opensearch-dashboards/opensearch-dashboards/apps/query_enhancements/{utils => helpers}/field_display_filtering.js (100%) rename cypress/integration/core-opensearch-dashboards/opensearch-dashboards/apps/query_enhancements/{utils => helpers}/saved_search.js (90%) create mode 100644 cypress/integration/core-opensearch-dashboards/opensearch-dashboards/apps/query_enhancements/helpers/sidebar_filtering.js create mode 100644 cypress/integration/core-opensearch-dashboards/opensearch-dashboards/apps/query_enhancements/sidebar_filtering.spec.js diff --git a/cypress/integration/core-opensearch-dashboards/opensearch-dashboards/apps/query_enhancements/field_display_filtering.spec.js b/cypress/integration/core-opensearch-dashboards/opensearch-dashboards/apps/query_enhancements/field_display_filtering.spec.js index 1069f2077db0..d1318098f8f1 100644 --- a/cypress/integration/core-opensearch-dashboards/opensearch-dashboards/apps/query_enhancements/field_display_filtering.spec.js +++ b/cypress/integration/core-opensearch-dashboards/opensearch-dashboards/apps/query_enhancements/field_display_filtering.spec.js @@ -12,7 +12,7 @@ import { END_TIME, DATASET_CONFIGS, } from '../../../../../utils/apps/constants'; -import * as dataExplorer from '../../../../../integration/core-opensearch-dashboards/opensearch-dashboards/apps/query_enhancements/utils/field_display_filtering.js'; +import * as fieldFiltering from './helpers/field_display_filtering'; import { SECONDARY_ENGINE, BASE_PATH } from '../../../../../utils/constants'; import { NEW_SEARCH_BUTTON } from '../../../../../utils/dashboards/data_explorer/elements.js'; @@ -22,10 +22,10 @@ const workspace = `${WORKSPACE_NAME}-${randomString}`; const selectDataset = (datasetType, language) => { switch (datasetType) { case 'index': - dataExplorer.selectIndexDataset(DATASOURCE_NAME, INDEX_NAME, language); + fieldFiltering.selectIndexDataset(DATASOURCE_NAME, INDEX_NAME, language); break; case 'index_pattern': - dataExplorer.selectIndexPatternDataset(INDEX_PATTERN_NAME, language); + fieldFiltering.selectIndexPatternDataset(INDEX_PATTERN_NAME, language); break; } }; @@ -43,21 +43,21 @@ const verifyTableFieldFilterActions = (datasetType, language, shouldExist) => { cy.getElementByTestId('docTable').get('tbody tr').should('have.length.above', 3); // To ensure it waits until a full table is loaded into the DOM, instead of a bug where table only has 1 hit. const shouldText = shouldExist ? 'exist' : 'not.exist'; - dataExplorer.getDocTableField(0, 0).within(() => { + fieldFiltering.getDocTableField(0, 0).within(() => { cy.getElementByTestId('filterForValue').should(shouldText); cy.getElementByTestId('filterOutValue').should(shouldText); }); if (shouldExist) { - dataExplorer.verifyDocTableFilterAction(0, 'filterForValue', '10,000', '1', true); - dataExplorer.verifyDocTableFilterAction(0, 'filterOutValue', '10,000', '9,999', false); + fieldFiltering.verifyDocTableFilterAction(0, 'filterForValue', '10,000', '1', true); + fieldFiltering.verifyDocTableFilterAction(0, 'filterOutValue', '10,000', '9,999', false); } }; const verifyExpandedTableFilterActions = (datasetType, language, isFilterButtonsEnabled) => { // Check if the first expanded Doc Table Field's first row's Filter For, Filter Out and Exists Filter buttons are disabled. const verifyFirstExpandedFieldFilterForFilterOutFilterExistsButtons = () => { const shouldText = isFilterButtonsEnabled ? 'be.enabled' : 'be.disabled'; - dataExplorer.getExpandedDocTableRow(0, 0).within(() => { + fieldFiltering.getExpandedDocTableRow(0, 0).within(() => { cy.getElementByTestId('addInclusiveFilterButton').should(shouldText); cy.getElementByTestId('removeInclusiveFilterButton').should(shouldText); cy.getElementByTestId('addExistsFilterButton').should(shouldText); @@ -89,11 +89,11 @@ const verifyExpandedTableFilterActions = (datasetType, language, isFilterButtons filterButton === 'for' ? 'addInclusiveFilterButton' : 'removeInclusiveFilterButton'; const shouldText = filterButton === 'for' ? 'have.text' : 'not.have.text'; - dataExplorer + fieldFiltering .getExpandedDocTableRowValue(docTableRowNumber, expandedDocumentRowNumber) .then(($expandedDocumentRowValue) => { const filterFieldText = $expandedDocumentRowValue.text(); - dataExplorer + fieldFiltering .getExpandedDocTableRow(docTableRowNumber, expandedDocumentRowNumber) .within(() => { cy.getElementByTestId(filterButtonElement).click(); @@ -104,7 +104,7 @@ const verifyExpandedTableFilterActions = (datasetType, language, isFilterButtons 'have.text', expectedQueryHitsAfterFilterApplied ); // checkQueryHitText must be in front of checking first line text to give time for DocTable to update. - dataExplorer + fieldFiltering .getExpandedDocTableRowValue(docTableRowNumber, expandedDocumentRowNumber) .should(shouldText, filterFieldText); }); @@ -125,11 +125,11 @@ const verifyExpandedTableFilterActions = (datasetType, language, isFilterButtons expectedQueryHitsWithoutFilter, expectedQueryHitsAfterFilterApplied ) => { - dataExplorer + fieldFiltering .getExpandedDocTableRowFieldName(docTableRowNumber, expandedDocumentRowNumber) .then(($expandedDocumentRowField) => { const filterFieldText = $expandedDocumentRowField.text(); - dataExplorer + fieldFiltering .getExpandedDocTableRow(docTableRowNumber, expandedDocumentRowNumber) .within(() => { cy.getElementByTestId('addExistsFilterButton').click(); @@ -154,9 +154,9 @@ const verifyExpandedTableFilterActions = (datasetType, language, isFilterButtons setDateRange(datasetType, language); cy.getElementByTestId('docTable').get('tbody tr').should('have.length.above', 3); // To ensure it waits until a full table is loaded into the DOM, instead of a bug where table only has 1 hit. - dataExplorer.toggleDocTableRow(0); + fieldFiltering.toggleDocTableRow(0); verifyFirstExpandedFieldFilterForFilterOutFilterExistsButtons(); - dataExplorer.verifyDocTableFirstExpandedFieldFirstRowToggleColumnButtonHasIntendedBehavior(); + fieldFiltering.verifyDocTableFirstExpandedFieldFirstRowToggleColumnButtonHasIntendedBehavior(); if (isFilterButtonsEnabled) { verifyDocTableFirstExpandedFieldFirstRowFilterForOutButtonFiltersCorrectField( @@ -181,6 +181,7 @@ const verifyExpandedTableFilterActions = (datasetType, language, isFilterButtons ); } }; + describe('filter for value spec', () => { before(() => { // Load test data diff --git a/cypress/integration/core-opensearch-dashboards/opensearch-dashboards/apps/query_enhancements/helpers/commons.js b/cypress/integration/core-opensearch-dashboards/opensearch-dashboards/apps/query_enhancements/helpers/commons.js new file mode 100644 index 000000000000..b7246bb3e14b --- /dev/null +++ b/cypress/integration/core-opensearch-dashboards/opensearch-dashboards/apps/query_enhancements/helpers/commons.js @@ -0,0 +1,75 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { + DatasetTypes, + DATASOURCE_NAME, + END_TIME, + INDEX_PATTERN_WITH_TIME, + INDEX_WITH_TIME_1, + QueryLanguages, + START_TIME, + WORKSPACE_NAME, +} from '../../../../../../utils/apps/query_enhancements/constants'; +// TODO: Make generateTestConfiguration more general and move it out from saved_search +import { generateTestConfiguration } from './saved_search'; + +const randomString = Math.random().toString(36); + +/** + * randomized workspace name + * @constant + * @type {string} + * @default + */ +export const workspaceName = `${WORKSPACE_NAME}-${randomString.substring(7)}`; + +/** + * randomized datasource name + * @constant + * @type {string} + * @default + */ +export const datasourceName = `${DATASOURCE_NAME}-${randomString.substring(0, 18)}`; + +/** + * Returns an array of test configurations for every query language + dataset permutation + * @returns {SavedSearchTestConfig[]} + */ +export const generateAllTestConfigurations = ( + indexPatternName = INDEX_PATTERN_WITH_TIME, + indexName = INDEX_WITH_TIME_1 +) => { + return Object.values(DatasetTypes).flatMap((dataset) => + dataset.supportedLanguages.map((language) => { + let datasetToUse; + switch (dataset.name) { + case DatasetTypes.INDEX_PATTERN.name: + datasetToUse = indexPatternName; + break; + case DatasetTypes.INDEXES.name: + datasetToUse = indexName; + break; + default: + throw new Error( + `generateAllTestConfigurations encountered unsupported dataset: ${dataset.name}` + ); + } + return generateTestConfiguration(datasetToUse, dataset.name, language); + }) + ); +}; + +/** + * Sets the top nav date if it is relevant for the passed language + * @param {QueryEnhancementLanguage} language - query language + */ +export const setDatePickerDatesAndSearchIfRelevant = (language) => { + if (language === QueryLanguages.SQL.name) { + return; + } + + cy.setTopNavDate(START_TIME, END_TIME); +}; diff --git a/cypress/integration/core-opensearch-dashboards/opensearch-dashboards/apps/query_enhancements/utils/field_display_filtering.js b/cypress/integration/core-opensearch-dashboards/opensearch-dashboards/apps/query_enhancements/helpers/field_display_filtering.js similarity index 100% rename from cypress/integration/core-opensearch-dashboards/opensearch-dashboards/apps/query_enhancements/utils/field_display_filtering.js rename to cypress/integration/core-opensearch-dashboards/opensearch-dashboards/apps/query_enhancements/helpers/field_display_filtering.js diff --git a/cypress/integration/core-opensearch-dashboards/opensearch-dashboards/apps/query_enhancements/utils/saved_search.js b/cypress/integration/core-opensearch-dashboards/opensearch-dashboards/apps/query_enhancements/helpers/saved_search.js similarity index 90% rename from cypress/integration/core-opensearch-dashboards/opensearch-dashboards/apps/query_enhancements/utils/saved_search.js rename to cypress/integration/core-opensearch-dashboards/opensearch-dashboards/apps/query_enhancements/helpers/saved_search.js index d95db5ef526e..3ca12a6518ae 100644 --- a/cypress/integration/core-opensearch-dashboards/opensearch-dashboards/apps/query_enhancements/utils/saved_search.js +++ b/cypress/integration/core-opensearch-dashboards/opensearch-dashboards/apps/query_enhancements/helpers/saved_search.js @@ -5,33 +5,9 @@ import { DatasetTypes, - DATASOURCE_NAME, - END_TIME, - INDEX_PATTERN_WITH_TIME, - INDEX_WITH_TIME_1, QueryLanguages, - START_TIME, - WORKSPACE_NAME, } from '../../../../../../utils/apps/query_enhancements/constants'; -const randomString = Math.random().toString(36); - -/** - * randomized workspace name - * @constant - * @type {string} - * @default - */ -export const workspaceName = `${WORKSPACE_NAME}-${randomString.substring(7)}`; - -/** - * randomized datasource name - * @constant - * @type {string} - * @default - */ -export const datasourceName = `${DATASOURCE_NAME}-${randomString.substring(0, 18)}`; - /** * The fields to select for saved search. Also takes shape of the API for saved search * @constant @@ -200,7 +176,7 @@ const getSampleTableData = (datasetType, language) => { * @param {QueryEnhancementLanguageData} language - the relevant data for the query language to use * @returns {SavedSearchTestConfig} */ -const generateTestConfiguration = (dataset, datasetType, language) => { +export const generateTestConfiguration = (dataset, datasetType, language) => { const baseConfig = { dataset, datasetType, @@ -219,43 +195,6 @@ const generateTestConfiguration = (dataset, datasetType, language) => { }; }; -/** - * Returns an array of test configurations for every query language + dataset permutation - * @returns {SavedSearchTestConfig[]} - */ -export const generateAllTestConfigurations = () => { - return Object.values(DatasetTypes).flatMap((dataset) => - dataset.supportedLanguages.map((language) => { - let datasetToUse; - switch (dataset.name) { - case DatasetTypes.INDEX_PATTERN.name: - datasetToUse = INDEX_PATTERN_WITH_TIME; - break; - case DatasetTypes.INDEXES.name: - datasetToUse = INDEX_WITH_TIME_1; - break; - default: - throw new Error( - `generateAllTestConfigurations encountered unsupported dataset: ${dataset.name}` - ); - } - return generateTestConfiguration(datasetToUse, dataset.name, language); - }) - ); -}; - -/** - * Sets the top nav date if it is relevant for the passed language - * @param {QueryEnhancementLanguage} language - query language - */ -export const setDatePickerDatesAndSearchIfRelevant = (language) => { - if (language === QueryLanguages.SQL.name) { - return; - } - - cy.setTopNavDate(START_TIME, END_TIME); -}; - /** * Set the search configurations for the saved search * @param {SavedSearchTestConfig} testConfig - the relevant config for the test case diff --git a/cypress/integration/core-opensearch-dashboards/opensearch-dashboards/apps/query_enhancements/helpers/sidebar_filtering.js b/cypress/integration/core-opensearch-dashboards/opensearch-dashboards/apps/query_enhancements/helpers/sidebar_filtering.js new file mode 100644 index 000000000000..64df13106d1b --- /dev/null +++ b/cypress/integration/core-opensearch-dashboards/opensearch-dashboards/apps/query_enhancements/helpers/sidebar_filtering.js @@ -0,0 +1,76 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * Sends a new query via the query multiline editor. + * @param {string} query Query string + * @see https://docs.cypress.io/api/commands/type#Arguments + */ +export const sendQueryOnMultilineEditor = (query) => { + // remove syntax helper + cy.getElementByTestId('headerGlobalNav').click(); + // Clear default text on the editor by an alternative method, since + // cy.clear() won't work for some reason + cy.get('.view-line') + .invoke('text') + .then(($content) => { + const contentLen = $content.length + 1; + cy.get('.view-line').type('a'); // make sure we're at the end of the string + cy.get('.view-line').type('{backspace}'.repeat(contentLen)); + }); + // Type query + cy.get('.view-line').type(query); + // Send query + cy.getElementByTestId('querySubmitButton').click(); +}; + +/** + * Click on the sidebar collapse button. + * @param {boolean} collapse true for collapsing, false for expanding + */ +export const clickSidebarCollapseBtn = (collapse = true) => { + if (collapse) { + cy.getElementByTestId('euiResizableButton').trigger('mouseover').click(); + } + cy.get('.euiResizableToggleButton').click({ force: true }); +}; + +/** + * Check the results of the sidebar filter bar search. + * @param {string} search text to look up + * @param {string} assertion the type of assertion that is going to be performed. Example: 'eq', 'include'. If an assertion is not passed, a negative test is performend. + */ +export const checkSidebarFilterBarResults = (search, assertion) => { + cy.getElementByTestId('fieldFilterSearchInput').type(search, { force: true }); + if (assertion) { + // Get all sidebar fields and iterate over all of them + cy.get('[data-test-subj^="field-"]:not([data-test-subj$="showDetails"])').each(($field) => { + cy.wrap($field) + .should('be.visible') + .invoke('text') + .then(($fieldTxt) => { + cy.wrap($fieldTxt).should(assertion, search); + }); + }); + } else { + // No match should be found + cy.get('[data-test-subj^="field-"]:not([data-test-subj$="showDetails"])').should('not.exist'); + } + cy.get('button[aria-label="Clear input"]').click(); +}; + +/** + * Removes all currently selected fields from the sidebar + */ +export const removeAllSelectedFields = () => { + cy.get('[data-test-subj="fieldList-selected"]').then(($list) => { + if ($list.find('[data-test-subj^="field-"]').length > 0) { + // Remove all selected fields + $list.find('[data-test-subj^="fieldToggle-"]').each((_, el) => { + cy.wrap(el).click(); + }); + } + }); +}; diff --git a/cypress/integration/core-opensearch-dashboards/opensearch-dashboards/apps/query_enhancements/saved_search.spec.js b/cypress/integration/core-opensearch-dashboards/opensearch-dashboards/apps/query_enhancements/saved_search.spec.js index f4cbdb228850..9f8c02101997 100644 --- a/cypress/integration/core-opensearch-dashboards/opensearch-dashboards/apps/query_enhancements/saved_search.spec.js +++ b/cypress/integration/core-opensearch-dashboards/opensearch-dashboards/apps/query_enhancements/saved_search.spec.js @@ -15,11 +15,13 @@ import { datasourceName, generateAllTestConfigurations, setDatePickerDatesAndSearchIfRelevant, +} from './helpers/commons'; +import { setSearchConfigurations, verifyDiscoverPageState, verifySavedSearchInAssetsPage, postRequestSaveSearch, -} from './utils/saved_search'; +} from './helpers/saved_search'; export const runSavedSearchTests = () => { describe('saved search', () => { diff --git a/cypress/integration/core-opensearch-dashboards/opensearch-dashboards/apps/query_enhancements/sidebar_filtering.spec.js b/cypress/integration/core-opensearch-dashboards/opensearch-dashboards/apps/query_enhancements/sidebar_filtering.spec.js new file mode 100644 index 000000000000..11b93c545c44 --- /dev/null +++ b/cypress/integration/core-opensearch-dashboards/opensearch-dashboards/apps/query_enhancements/sidebar_filtering.spec.js @@ -0,0 +1,265 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { SECONDARY_ENGINE } from '../../../../../utils/constants'; +import { + workspaceName, + datasourceName, + generateAllTestConfigurations, + setDatePickerDatesAndSearchIfRelevant, +} from './helpers/commons'; +import * as fieldFiltering from './helpers/field_display_filtering'; +import * as sidebarFiltering from './helpers/sidebar_filtering'; + +const addSidebarFieldsAndCheckDocTableColumns = ( + testFields, + expectedValues, + pplQuery, + sqlQuery, + config +) => { + // Helper functions + const getDocTableHeaderByIndex = (index) => + cy.getElementByTestId('docTableHeaderField').eq(index); + + const checkTableHeaders = (headers) => { + headers.forEach((header, index) => { + getDocTableHeaderByIndex(index + 1).should('have.text', header); + }); + }; + + const checkDocTableColumn = (values, columnNumber) => { + values.forEach((value, index) => { + fieldFiltering.getDocTableField(columnNumber, index).should('have.text', value); + }); + }; + + const toggleFields = (fields) => { + fields.forEach((field) => { + cy.getElementByTestId(`fieldToggle-${field}`).click(); + }); + }; + + // Test field toggling and header persistence + cy.wrap([ + // Check initial state + () => getDocTableHeaderByIndex(1).should('have.text', '_source'), + + // Add fields and verify + () => { + toggleFields(testFields); + getDocTableHeaderByIndex(1).should('not.have.text', '_source'); + checkTableHeaders(testFields); + }, + + // Test field removal + () => { + // Remove first two fields + toggleFields(testFields.slice(0, 2)); + getDocTableHeaderByIndex(1).should('not.have.text', testFields[0]); + getDocTableHeaderByIndex(2).should('not.have.text', testFields[1]); + + // Remove remaining fields + toggleFields(testFields.slice(2)); + getDocTableHeaderByIndex(1).should('have.text', '_source'); + getDocTableHeaderByIndex(2).should('not.exist'); + + // Add all fields back + toggleFields(testFields); + getDocTableHeaderByIndex(1).should('not.have.text', '_source'); + checkTableHeaders(testFields); + }, + ]).each((fn) => fn()); + + // Check default hits only for index pattern before running queries + if (isIndexPattern && config.language !== 'OpenSearch SQL') { + cy.getElementByTestId('discoverQueryHits').should('have.text', '10,000'); + } + + // Run query based on language type + if (config.language === 'PPL') { + cy.intercept('**/api/enhancements/search/ppl').as('query'); + sidebarFiltering.sendQueryOnMultilineEditor(pplQuery); + cy.wait('@query').then(() => { + checkTableHeaders(testFields); + if (isIndexPattern) { + cy.getElementByTestId('discoverQueryHits').should('have.text', '1,152'); + } + checkDocTableColumn(expectedValues, 2); + //toggleFields(testFields); + }); + } else if (config.language === 'OpenSearch SQL') { + cy.intercept('**/api/enhancements/search/sql').as('query'); + sidebarFiltering.sendQueryOnMultilineEditor(sqlQuery); + cy.wait('@query').then(() => { + checkTableHeaders(testFields); + checkDocTableColumn(expectedValues, 2); + //toggleFields(testFields); + }); + } else if (config.language === 'DQL' || config.language === 'Lucene') { + // For DQL and Lucene, just verify the headers safter toggleFields + checkTableHeaders(testFields); + //toggleFields(testFields); + } +}; + +const checkFilteredFieldsForAllLanguages = () => { + const searchValues = [ + { search: '_index', assertion: 'equal' }, + { search: ' ', assertion: null }, + { search: 'a', assertion: 'include' }, + { search: 'age', assertion: 'include' }, + { search: 'non-existent field', assertion: null }, + ]; + + searchValues.forEach(({ search, assertion }) => { + sidebarFiltering.checkSidebarFilterBarResults(search, assertion); + }); +}; + +const checkSidebarPanelCollapseAndExpandBehavior = () => { + // Helper function to check panel visibility + const checkPanelVisibility = (shouldBeVisible) => { + cy.getElementByTestId('sidebarPanel').should(shouldBeVisible ? 'be.visible' : 'not.be.visible'); + }; + + // Test collapse + checkPanelVisibility(true); + sidebarFiltering.clickSidebarCollapseBtn(); + checkPanelVisibility(false); + + // Test expand + sidebarFiltering.clickSidebarCollapseBtn(false); + checkPanelVisibility(true); +}; + +const checkSidebarPanelCollapsedState = () => { + sidebarFiltering.clickSidebarCollapseBtn(); + cy.getElementByTestId('sidebarPanel').should('not.be.visible'); + sidebarFiltering.clickSidebarCollapseBtn(false); +}; + +describe('sidebar spec', () => { + before(() => { + // Load test data + cy.setupTestData( + SECONDARY_ENGINE.url, + ['cypress/fixtures/query_enhancements/data-logs-1/data_logs_small_time_1.mapping.json'], + ['cypress/fixtures/query_enhancements/data-logs-1/data_logs_small_time_1.data.ndjson'] + ); + // Clean out all data sources + cy.deleteAllDataSources(); + // Add data source + cy.addDataSource({ + name: datasourceName, + url: SECONDARY_ENGINE.url, + authType: 'no_auth', + }); + // Create workspace + cy.deleteWorkspaceByName(`${workspaceName}`); + cy.visit('/app/home'); + cy.createInitialWorkspaceWithDataSource(datasourceName, workspaceName); + cy.wait(2000); + cy.createWorkspaceIndexPatterns({ + workspaceName: workspaceName, + indexPattern: 'data_logs_small_time_1', + timefieldName: 'timestamp', + dataSource: datasourceName, + isEnhancement: true, + }); + cy.navigateToWorkSpaceSpecificPage({ + workspaceName: workspaceName, + page: 'discover', + isEnhancement: true, + }); + }); + + after(() => { + cy.deleteWorkspaceByName(`${workspaceName}`); + cy.deleteDataSourceByName(datasourceName); + cy.deleteIndex('data_logs_small_time_1'); + }); + + afterEach(() => { + // Clear any applied filters or selections + cy.window().then((win) => { + win.localStorage.clear(); + win.sessionStorage.clear(); + }); + cy.reload(); + }); + + describe('sidebar fields', () => { + generateAllTestConfigurations('data_logs_small_time_1*', 'data_logs_small_time_1').forEach( + (config) => { + const testData = { + pplQuery: `source = ${config.dataset} | where status_code = 200`, + sqlQuery: `SELECT * FROM ${config.dataset} WHERE status_code = 200`, + simpleFields: { + fields: ['service_endpoint', 'response_time', 'bytes_transferred', 'request_url'], + expectedValues: ['3.32', '2.8', '3.35', '1.68', '4.98'], + }, + nestedFields: { + fields: [ + 'personal.name', + 'personal.age', + 'personal.birthdate', + 'personal.address.country', + ], + expectedValues: ['28', '55', '76', '56', '36'], + }, + }; + describe(`${config.testName}`, () => { + beforeEach(() => { + cy.setDataset(config.dataset, datasourceName, config.datasetType); + cy.setQueryLanguage(config.language); + setDatePickerDatesAndSearchIfRelevant(config.language); + + // Clean up any existing fields + sidebarFiltering.removeAllSelectedFields(); + }); + + describe('add fields', () => { + it('adds simple fields', () => { + addSidebarFieldsAndCheckDocTableColumns( + testData.simpleFields.fields, + testData.simpleFields.expectedValues, + testData.pplQuery, + testData.sqlQuery, + config.datasetType === 'INDEX_PATTERN', + config + ); + }); + + it('adds nested fields', () => { + addSidebarFieldsAndCheckDocTableColumns( + testData.nestedFields.fields, + testData.nestedFields.expectedValues, + testData.pplQuery, + testData.sqlQuery, + config.datasetType === 'INDEX_PATTERN', + config + ); + }); + }); + + describe('filter fields', () => { + it('filters fields correctly', () => { + checkFilteredFieldsForAllLanguages(config.datasetType === 'INDEX_PATTERN'); + }); + }); + + describe('side panel behavior', () => { + it('handles panel collapse/expand correctly', () => { + checkSidebarPanelCollapseAndExpandBehavior(config.datasetType === 'INDEX_PATTERN'); + cy.wait(1000); + checkSidebarPanelCollapsedState(config.datasetType === 'INDEX_PATTERN'); + }); + }); + }); + } + ); + }); +});