Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TESTID-66: histogram tests #9290

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import {
START_TIME,
END_TIME,
INDEX_PATTERN_WITH_TIME,
INDEX_WITH_TIME_1,
QueryLanguages,
} from '../../../../../utils/apps/constants';
import { SECONDARY_ENGINE, BASE_PATH } from '../../../../../utils/constants';
import { NEW_SEARCH_BUTTON } from '../../../../../utils/dashboards/data_explorer/elements.js';
import {
generateAllTestConfigurations,
getRandomizedWorkspaceName,
getRandomizedDatasourceName,
setDatePickerDatesAndSearchIfRelevant,
} from '../../../../../utils/apps/query_enhancements/shared';
import { generateHistogramTestConfigurations } from '../../../../../utils/apps/query_enhancements/histogram_interaction';
import { DatasetTypes } from '../../../../../utils/apps/query_enhancements/constants';

const workspace = getRandomizedWorkspaceName();
const datasource = getRandomizedDatasourceName();

describe('histogram interaction', { testIsolation: true }, () => {
beforeEach(() => {
// 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']
);

// Add data source
cy.addDataSource({
name: datasource,
url: `${SECONDARY_ENGINE.url}`,
authType: 'no_auth',
});
// Create workspace
cy.deleteWorkspaceByName(workspace);
cy.visit('/app/home');
cy.osd.createInitialWorkspaceWithDataSource(datasource, workspace);
cy.createWorkspaceIndexPatterns({
workspaceName: workspace,
indexPattern: INDEX_PATTERN_WITH_TIME.replace('*', ''),
timefieldName: 'timestamp',
indexPatternHasTimefield: true,
dataSource: datasource,
isEnhancement: true,
});
cy.navigateToWorkSpaceSpecificPage({
url: BASE_PATH,
workspaceName: workspace,
page: 'discover',
isEnhancement: true,
});
cy.getElementByTestId(NEW_SEARCH_BUTTON).click();
});

afterEach(() => {
cy.deleteWorkspaceByName(workspace);
cy.deleteDataSourceByName(datasource);
// TODO: Modify deleteIndex to handle an array of index and remove hard code
cy.deleteIndex(INDEX_WITH_TIME_1);
});

generateAllTestConfigurations(generateHistogramTestConfigurations).forEach((config) => {
it(`check histogram visibility for ${config.testName}`, () => {
cy.setDataset(config.dataset, datasource, config.datasetType);
cy.setQueryLanguage(config.language);
setDatePickerDatesAndSearchIfRelevant(config.language);
if (config.isHistogramVisible) {
cy.getElementByTestId('dscChartChartheader').should('be.visible');
cy.getElementByTestId('discoverChart').should('be.visible');
} else {
cy.getElementByTestId('dscChartChartheader').should('not.exist');
cy.getElementByTestId('discoverChart').should('not.exist');
}
// check interval selection persistence across language changes.
// Only need to check for INDEX_PATTERNS because INDEXES
// only supports SQL & PPL, and only one of the two supports histogram.
if (config.isHistogramVisible && config.datasetType === DatasetTypes.INDEX_PATTERN.name) {
cy.getElementByTestId('discoverIntervalSelect').select('Week');
cy.getElementByTestId('discoverIntervalDateRange').contains(
`${START_TIME} - ${END_TIME} per`
);
for (const language of DatasetTypes.INDEX_PATTERN.supportedLanguages) {
if (language.name === QueryLanguages.SQL.name) continue;
cy.setQueryLanguage(language.name);
cy.wait(1000); // wait a bit to ensure data is loaded
if (language.supports.histogram) {
cy.getElementByTestId('discoverIntervalSelect').select('Week');
cy.getElementByTestId('discoverIntervalDateRange').contains(
`${START_TIME} - ${END_TIME} per`
);
}
}
}
});

it(`check the Auto interval value for ${config.testName}`, () => {
if (!config.isHistogramVisible) return;
cy.setDataset(config.dataset, datasource, config.datasetType);
cy.setQueryLanguage(config.language);
setDatePickerDatesAndSearchIfRelevant(config.language);
const intervals = ['auto', 'ms', 's', 'm', 'h', 'd', 'w', 'M', 'y'];
cy.getElementByTestId('discoverIntervalSelect').should('have.value', intervals[0]);
intervals.forEach((interval) => {
cy.getElementByTestId('discoverIntervalSelect').select(interval);
cy.wait(1000); // adding a wait here to ensure the data has been updated
config.langPermutation.forEach((lang) => {
if (lang === QueryLanguages.SQL.name) return;
cy.setQueryLanguage(lang);
cy.getElementByTestId('discoverIntervalSelect').should('have.value', interval);
cy.getElementByTestId('discoverIntervalDateRange').should('be.visible');
});
});
// TODO: check histogram visualization
});

it(`check the time range selection for ${config.testName}`, () => {
const TIME = '13:00:00.000';
const START_DATE = `Jan 1, 2021 @ ${TIME}`;
const END_DATE = `Oct 1, 2021 @ ${TIME}`;
const checkIntervals = () => {
cy.getElementByTestId('discoverIntervalDateRange')
.should('be.visible')
.and('have.text', `${START_DATE} - ${END_DATE} per`);
cy.getElementByTestId('docTableExpandToggleColumn')
.eq(0)
.find('button')
.click({ force: true });
cy.getElementByTestId('tableDocViewRow-timestamp-value').then(($timestamp) => {
const timestampTxt = $timestamp.text();
const parsedDate = timestampTxt.split('@');
const date = parsedDate[0].trim();
const actualTime = parsedDate[1].trim();
const parsedExpectedTime = new Date(`1970-01-01T${TIME}`);
const parsedActualTime = new Date(`1970-01-01T${actualTime}`);
expect(timestampTxt).to.contain(date);
expect(parsedActualTime <= parsedExpectedTime).to.equal(true);
});
cy.getElementByTestId('docTableExpandToggleColumn')
.eq(0)
.find('button')
.click({ force: true }); // reset state
};
cy.setDataset(config.dataset, datasource, config.datasetType);
cy.setQueryLanguage(config.language);
if (config.isHistogramVisible) {
if (config.language !== 'PPL') {
// remove after the bug is fixed
cy.setTopNavDate(START_DATE, END_DATE);
cy.wait(1000); // adding a wait here to ensure the data has been updated
checkIntervals();
cy.getElementByTestId('discoverQueryHits').then(($hits) => {
const hitsTxt = $hits.text();
const langs = config.langPermutation;
langs.splice(langs.indexOf('PPL'), 1); // remove after the bug is fixed
langs.forEach((lang) => {
if (lang === QueryLanguages.SQL.name) return;
cy.setQueryLanguage(lang);
cy.wait(1000); // adding a wait here to ensure the data has been updated
cy.getElementByTestId('discoverQueryHits').should('have.text', hitsTxt);
checkIntervals();
});
});
}
} else {
cy.getElementByTestId('discoverIntervalSelect').should('not.exist');
}
});

it(`check collapse/expand functionality and state persistence for ${config.testName}`, () => {
if (!config.isHistogramVisible) return;
cy.setDataset(config.dataset, datasource, config.datasetType);
cy.setQueryLanguage(config.language);
setDatePickerDatesAndSearchIfRelevant(config.language);

cy.getElementByTestId('dscChartChartheader').should('be.visible');
cy.getElementByTestId('discoverChart').should('be.visible');
cy.getElementByTestId('histogramCollapseBtn').should('be.visible').click();
cy.getElementByTestId('dscChartChartheader').should('be.visible');
cy.getElementByTestId('discoverChart').should('not.exist');

const permutation = {
collapse: 'not.exist',
expand: 'be.visible',
};
Object.keys(permutation).forEach((perm) => {
config.langPermutation.forEach((lang) => {
cy.setQueryLanguage(lang);
cy.getElementByTestId('dscChartChartheader').should('be.visible');
cy.getElementByTestId('discoverChart').should(permutation[perm]);
// Uncomment after reload bug is fixed
//cy.reload(); // should not remove cache for the test to be meaningful
//cy.getElementByTestId('discoverChart').should(permutation[perm]);
//cy.getElementByTestId('histogramCollapseBtn').should(permutation[perm]);
});
if (perm === 'collapse') {
// start again from the beginning and expand again
cy.setQueryLanguage(config.language);
cy.getElementByTestId('histogramCollapseBtn').should('be.visible').click();
}
});
});
});
});
59 changes: 59 additions & 0 deletions cypress/utils/apps/query_enhancements/histogram_interaction.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import { DatasetTypes, QueryLanguages } from './constants';

export const HistogramDatasetTypes = {
INDEX_PATTERN: {
name: 'INDEX_PATTERN',
supportedLanguages: [QueryLanguages.DQL, QueryLanguages.SQL, QueryLanguages.PPL],
},
INDEXES: {
name: 'INDEXES',
supportedLanguages: [QueryLanguages.PPL],
},
};

/**
* The configurations needed for field display filtering tests
* @typedef {Object} HistogramTestConfig
* @property {string} dataset - the dataset name to use
* @property {QueryEnhancementDataset} datasetType - the type of dataset
* @property {QueryEnhancementLanguage} language - the name of query language as it appears in the dashboard app
* @property {string} testName - the phrase to add to the test case's title
*/

/**
* Returns the SavedSearchTestConfig for the provided dataset, datasetType, and language
* @param {string} dataset - the dataset name
* @param {QueryEnhancementDataset} datasetType - the type of the dataset
* @param {QueryEnhancementLanguageData} language - the relevant data for the query language to use
* @returns {HistogramTestConfig}
*/
export const generateHistogramTestConfigurations = (dataset, datasetType, language) => {
const isHistogramVisible = language.name === QueryLanguages.SQL.name ? false : true;
let langPermutation;
if (datasetType === DatasetTypes.INDEX_PATTERN.name) {
// access the supportedLanguages object and converting it into an array
// then iterate over each one of them and create a new array with just the names of the languages
// the [1] there is because Object.entries places the object we want in the second place on the array
langPermutation = Object.entries(HistogramDatasetTypes.INDEX_PATTERN.supportedLanguages).map(
(lang) => lang[1].name
);
langPermutation.splice(langPermutation.indexOf(language.name), 1); // remove current lang to iterate over the other two only
} else {
langPermutation = Object.entries(HistogramDatasetTypes.INDEXES.supportedLanguages).map(
(lang) => lang[1].name
);
}
return {
dataset,
datasetType: HistogramDatasetTypes[datasetType].name,
language: language.name,
langPermutation: langPermutation,
isHistogramVisible: isHistogramVisible,
testName: `dataset: ${datasetType} and language: ${language.name}`,
silvaf-dev marked this conversation as resolved.
Show resolved Hide resolved
};
};
13 changes: 9 additions & 4 deletions cypress/utils/apps/query_enhancements/shared.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,18 +49,23 @@ export const getRandomizedDatasourceName = () =>
* @param {Object} [options] - Optional configuration options
* @param {string} [options.indexPattern] - Custom index pattern name (defaults to INDEX_PATTERN_WITH_TIME)
* @param {string} [options.index] - Custom index name (defaults to INDEX_WITH_TIME_1)
* @param {Object.<QueryEnhancementDataset, QueryEnhancementDatasetData>} [options.datasetTypes] - Custom dataset types (defaults to DatasetTypes)
* @returns {object[]}
*/
export const generateAllTestConfigurations = (generateTestConfigurationCallback, options = {}) => {
const { indexPattern = INDEX_PATTERN_WITH_TIME, index = INDEX_WITH_TIME_1 } = options;
return Object.values(DatasetTypes).flatMap((dataset) =>
const {
indexPattern = INDEX_PATTERN_WITH_TIME,
index = INDEX_WITH_TIME_1,
datasetTypes = DatasetTypes,
} = options;
return Object.values(datasetTypes).flatMap((dataset) =>
dataset.supportedLanguages.map((language) => {
let datasetToUse;
switch (dataset.name) {
case DatasetTypes.INDEX_PATTERN.name:
case datasetTypes.INDEX_PATTERN.name:
datasetToUse = indexPattern;
break;
case DatasetTypes.INDEXES.name:
case datasetTypes.INDEXES.name:
datasetToUse = index;
break;
default:
Expand Down
Loading