-
Notifications
You must be signed in to change notification settings - Fork 968
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Anan Zhuang <ananzh@amazon.com>
- Loading branch information
Showing
6 changed files
with
350 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
test: | ||
- Add all recent queries tests ([#9307](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/9307)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
233 changes: 233 additions & 0 deletions
233
...pensearch_dashboards/opensearch_dashboards/apps/query_enhancements/recent_queries.spec.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,233 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
import { | ||
DATASOURCE_NAME, | ||
INDEX_PATTERN_WITH_TIME, | ||
INDEX_WITH_TIME_1, | ||
} from '../../../../../utils/apps/constants'; | ||
import { BASE_PATH, PATHS } from '../../../../../utils/constants'; | ||
import { | ||
getRandomizedWorkspaceName, | ||
setDatePickerDatesAndSearchIfRelevant, | ||
generateAllTestConfigurations, | ||
} from '../../../../../utils/apps/query_enhancements/shared'; | ||
import { | ||
generateRecentQueriesTestConfiguration, | ||
BaseQuery, | ||
TestQueries, | ||
//TODO: QueryRegex, | ||
} from '../../../../../utils/apps/query_enhancements/recent_queries'; | ||
import { prepareTestSuite } from '../../../../../utils/helpers'; | ||
|
||
const workspace = getRandomizedWorkspaceName(); | ||
const runRecentQueryTests = () => { | ||
describe('recent queries spec', { testIsolation: true }, () => { | ||
const index = INDEX_PATTERN_WITH_TIME.replace('*', ''); | ||
beforeEach(() => { | ||
// Load test data | ||
cy.osd.setupTestData( | ||
PATHS.SECONDARY_ENGINE, | ||
['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.osd.addDataSource({ | ||
name: DATASOURCE_NAME, | ||
url: `${PATHS.SECONDARY_ENGINE}`, | ||
authType: 'no_auth', | ||
}); | ||
// Create workspace | ||
cy.deleteWorkspaceByName(workspace); | ||
cy.visit('/app/home'); | ||
cy.osd.createInitialWorkspaceWithDataSource(DATASOURCE_NAME, workspace); | ||
cy.createWorkspaceIndexPatterns({ | ||
workspaceName: workspace, | ||
indexPattern: index, | ||
timefieldName: 'timestamp', | ||
indexPatternHasTimefield: true, | ||
dataSource: DATASOURCE_NAME, | ||
isEnhancement: true, | ||
}); | ||
|
||
cy.navigateToWorkSpaceSpecificPage({ | ||
url: BASE_PATH, | ||
workspaceName: workspace, | ||
page: 'discover', | ||
isEnhancement: true, | ||
}); | ||
}); | ||
|
||
afterEach(() => { | ||
cy.deleteWorkspaceByName(workspace); | ||
cy.osd.deleteDataSourceByName(DATASOURCE_NAME); | ||
// TODO: Modify deleteIndex to handle an array of index and remove hard code | ||
cy.osd.deleteIndex(INDEX_WITH_TIME_1); | ||
}); | ||
|
||
generateAllTestConfigurations(generateRecentQueriesTestConfiguration) | ||
.filter(Boolean) // removes undefined values | ||
.forEach((config) => { | ||
it(`check max queries for ${config.testName}`, () => { | ||
cy.setDataset(config.dataset, DATASOURCE_NAME, config.datasetType); | ||
cy.setQueryLanguage(config.language); | ||
setDatePickerDatesAndSearchIfRelevant(config.language); | ||
const currentLang = BaseQuery[config.datasetType][config.language]; | ||
const currentBaseQuery = currentLang.query; | ||
const currentWhereStatement = currentLang.where; | ||
TestQueries.forEach((query) => { | ||
cy.setQueryEditor( | ||
currentBaseQuery + config.dataset + currentWhereStatement + query, | ||
{}, | ||
true | ||
); | ||
}); | ||
cy.getElementByTestId('queryEditorFooterToggleRecentQueriesButton').click({ | ||
force: true, | ||
}); | ||
// only 10 of the 11 queries should be displayed | ||
cy.getElementByTestIdLike('row-').should('have.length', 10); | ||
const reverseList = [...TestQueries].reverse(); | ||
const steps = [ | ||
{ | ||
// only check the table | ||
action: () => {}, | ||
}, | ||
{ | ||
// check table after changing language and returning to the language under test | ||
action: () => { | ||
cy.setQueryLanguage(config.oppositeLang); | ||
cy.setQueryLanguage(config.language); | ||
cy.wrap(null).then(() => { | ||
// force Cypress to run this method in order | ||
reverseList.unshift(config.defaultQuery); | ||
}); | ||
}, | ||
}, | ||
{ | ||
// check table after changing dataset and returning to the dataset under test | ||
action: () => { | ||
cy.setIndexAsDataset( | ||
config.alternativeDataset, | ||
DATASOURCE_NAME, | ||
config.language, | ||
"I don't want to use the time filter" | ||
); | ||
cy.setDataset(config.dataset, DATASOURCE_NAME, config.datasetType); | ||
cy.wrap(null).then(() => { | ||
// force Cypress to run this method in order | ||
reverseList.unshift(config.defaultQuery); | ||
}); | ||
}, | ||
}, | ||
{ | ||
// check table after visiting a different URL and coming back to the workspace | ||
action: () => { | ||
cy.visit('/app/workspace_initial'); | ||
cy.navigateToWorkSpaceSpecificPage({ | ||
url: BASE_PATH, | ||
workspaceName: workspace, | ||
page: 'discover', | ||
isEnhancement: true, | ||
}); | ||
cy.getElementByTestId('queryEditorFooterToggleRecentQueriesButton').click({ | ||
force: true, | ||
}); | ||
}, | ||
}, | ||
]; | ||
steps.forEach(({ action }, stepIndex) => { | ||
action(); | ||
cy.getElementByTestIdLike('row-').each(($row, rowIndex) => { | ||
let expectedQuery = ''; | ||
if (rowIndex === 1 && stepIndex >= 2) { | ||
expectedQuery = | ||
currentBaseQuery + config.alternativeDataset + reverseList[rowIndex]; | ||
} else if (rowIndex === 0 && stepIndex >= 1) { | ||
expectedQuery = currentBaseQuery + config.dataset + reverseList[rowIndex]; | ||
} else { | ||
expectedQuery = | ||
currentBaseQuery + config.dataset + currentWhereStatement + reverseList[rowIndex]; | ||
} | ||
expect($row.text()).to.contain(expectedQuery); | ||
}); | ||
}); | ||
}); | ||
|
||
it(`check duplicate query for ${config.testName}`, () => { | ||
cy.setDataset(config.dataset, DATASOURCE_NAME, config.datasetType); | ||
cy.setQueryLanguage(config.language); | ||
setDatePickerDatesAndSearchIfRelevant(config.language); | ||
const currentLang = BaseQuery[config.datasetType][config.language]; | ||
const currentBaseQuery = currentLang.query; | ||
const currentWhereStatement = currentLang.where; | ||
const testQueries = [ | ||
currentBaseQuery + config.dataset + currentWhereStatement + ' status_code = 504', // valid | ||
currentBaseQuery + config.dataset + currentWhereStatement, // invalid | ||
]; | ||
testQueries.forEach((query, index) => { | ||
cy.setQueryEditor(query, {}, true); | ||
cy.setQueryEditor(query, {}, true); | ||
if (!index) | ||
// it remains expanded for the second iteration, no need to expand it again | ||
cy.getElementByTestId('queryEditorFooterToggleRecentQueriesButton').click({ | ||
force: true, | ||
}); | ||
cy.getElementByTestIdLike('row-').should('have.length', index + 2); | ||
}); | ||
}); | ||
|
||
/* TODO: adding these tests requires adding a dependency OR customizing the execSync function | ||
//const { execSync } = require('child_process'); | ||
//console.log(execSync('xclip -selection clipboard -o').toString().trim()); // for Linux | ||
//Caveat: the commands for reading the system's clipboard is OS-dependent. | ||
it(`check running and copying recent queries for ${config.testName}`, () => { | ||
cy.setDataset(config.dataset, DATASOURCE_NAME, config.datasetType); | ||
cy.setQueryLanguage(config.language); | ||
setDatePickerDatesAndSearchIfRelevant(config.language); | ||
// Precondition: run some queries first | ||
const currentLang = BaseQuery[config.datasetType][config.language]; | ||
const currentBaseQuery = currentLang.query + config.dataset + currentLang.where; | ||
const queries = [...TestQueries].splice(0, 3); | ||
queries.forEach((query) => { | ||
cy.setQueryEditor(currentBaseQuery + query, {}, true); | ||
}); | ||
cy.getElementByTestId('queryEditorFooterToggleRecentQueriesButton').click({ | ||
force: true, | ||
}); | ||
const expectedQuery = currentBaseQuery + queries[0]; | ||
cy.getElementByTestIdLike('row-') // check query in original position | ||
.eq(2) | ||
.focus() | ||
.then(($row) => { | ||
expect($row.text()).to.include(expectedQuery); | ||
}); | ||
cy.getElementByTestId('action-run').eq(2).focus().click({ force: true }); // run query again | ||
cy.wait(2000); | ||
cy.getElementByTestIdLike('row-') // check query in altered position | ||
.eq(0) | ||
.focus() | ||
.then(($row) => { | ||
expect($row.text()).to.include(expectedQuery); | ||
}); | ||
cy.getElementByTestIdLike('row-') // copy another query to clipboard | ||
.eq(1) | ||
.focus() | ||
.then(($row) => { | ||
cy.get('[aria-label="Copy recent query"]').eq(1).click({ force: true }); | ||
cy.wait(1000); // Give the clipboard some time to update | ||
const expectedQuery = $row.text().replace(QueryRegex[config.language], '$1'); | ||
cy.get('[aria-label="Copy recent query"]').eq(1).focus(); | ||
cy.task('readClipboard').then((clipboardText) => { | ||
expect(clipboardText).to.eq(expectedQuery); | ||
}); | ||
}); | ||
});*/ | ||
}); | ||
}); | ||
}; | ||
|
||
prepareTestSuite('Recent Query', runRecentQueryTests); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
import { QueryLanguages } from './constants'; | ||
|
||
export const RecentQueriesDataTypes = { | ||
INDEX_PATTERN: { | ||
name: 'INDEX_PATTERN', | ||
supportedLanguages: [QueryLanguages.SQL, QueryLanguages.PPL], | ||
}, | ||
INDEXES: { | ||
name: 'INDEXES', | ||
supportedLanguages: [QueryLanguages.SQL, QueryLanguages.PPL], | ||
}, | ||
}; | ||
|
||
export const BaseQuery = { | ||
INDEX_PATTERN: { | ||
'OpenSearch SQL': { | ||
query: `SELECT * FROM `, | ||
where: ' WHERE ', | ||
}, | ||
PPL: { | ||
query: `source = `, | ||
where: ' | where ', | ||
}, | ||
}, | ||
INDEXES: { | ||
'OpenSearch SQL': { | ||
query: `SELECT * FROM `, | ||
where: ' WHERE ', | ||
}, | ||
PPL: { | ||
query: `source = `, | ||
where: ' | where ', | ||
}, | ||
}, | ||
}; | ||
|
||
export const TestQueries = [ | ||
'bytes_transferred >', | ||
'bytes_transferred < 8000', | ||
'bytes_transferred > 8000', | ||
'status_code = 404', | ||
'status_code = 501', | ||
'status_code = 503', | ||
'status_code = 400', | ||
'status_code = 401', | ||
'status_code = 403', | ||
'status_code = 200', | ||
'event_sequence_number > 10000000', | ||
]; | ||
|
||
/* // TODO | ||
export const QueryRegex = { | ||
PPL: /.*?(source .*? 8000)(?:.*)/s, | ||
'OpenSearch SQL': /.*?(SELECT .*? 8000)(?:.*)/s, | ||
};*/ | ||
|
||
/** | ||
* The configurations needed for recent queries tests | ||
* @typedef {Object} RecentQueriesFilteringTestConfig | ||
* @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 {RecentQueriesFilteringTestConfig} | ||
*/ | ||
export const generateRecentQueriesTestConfiguration = (dataset, datasetType, language) => { | ||
if (language.name !== 'PPL' && language.name !== 'OpenSearch SQL') { | ||
return; // undefined | ||
} | ||
const oppositeLang = { | ||
PPL: 'OpenSearch SQL', | ||
'OpenSearch SQL': 'PPL', | ||
}; | ||
const defaultQuery = language.name === 'PPL' ? '' : ' LIMIT 10'; | ||
const customDatasetType = RecentQueriesDataTypes[datasetType].name; | ||
return { | ||
dataset, | ||
datasetType: customDatasetType, | ||
language: language.name, | ||
oppositeLang: oppositeLang[language.name], | ||
alternativeDataset: '.opensearch-sap-log-types-config', | ||
defaultQuery: defaultQuery, | ||
testName: `dataset: ${datasetType} and language: ${language.name}`, | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters