Skip to content

Commit

Permalink
[Table visualization] Add functional tests for new table vis (#423)
Browse files Browse the repository at this point in the history
* [Table visualization] Add functional tests for new table vis

There are four test cases:
* basic.spec.js contains tests related to vis page, like
inspector, save an object.
* data.spec.js tests diff metrics and buckets aggregations.
* options.spec.js contains tests on options panel.
* split.spec.js tests table functions, like sort, adjust col
width, split tables and etc.

Most tests are the same as the removed funtional tests.
split.spec.js is the only one with all new tests.

Partially Resolved:
#401

Signed-off-by: Anan Zhuang <[email protected]>

* fix PR comments

Signed-off-by: Anan Zhuang <[email protected]>

* fix test error and add embed test suite

Signed-off-by: Anan Zhuang <[email protected]>

* Fix multiple submit bug
Currently there are two submit type button in data source
which cause cypress fail to find and click. In this PR, I
switch to use data-test-subj to uniquely identify the btn.

Issue Resolved:
#439

Signed-off-by: Anan Zhuang <[email protected]>

* missed conflict resolution

Signed-off-by: Kawika Avilla <[email protected]>

---------

Signed-off-by: Anan Zhuang <[email protected]>
Signed-off-by: Kawika Avilla <[email protected]>
Co-authored-by: Kawika Avilla <[email protected]>
  • Loading branch information
ananzh and kavilla authored May 24, 2023
1 parent 8dbfb0f commit 3dffb5f
Show file tree
Hide file tree
Showing 17 changed files with 21,894 additions and 0 deletions.
20,000 changes: 20,000 additions & 0 deletions cypress/fixtures/dashboard/opensearch_dashboards/vis_type_table/table.data.txt

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{"id":"index-pattern-vis-table","type":"index-pattern","namespaces":["default"],"updated_at":"2022-12-05T21:14:35.148Z","version":"WzUwLDFd","attributes":{"title":"vis-table","timeFieldName":"timestamp"},"references":[],"migrationVersion":{"index-pattern":"7.6.0"}}
{"id":"f3f0a6f0-74de-11ed-9a2e-2509e8c9c014","type":"visualization","namespaces":["default"],"updated_at":"2022-12-05T20:54:04.254Z","version":"WzQ0LDFd","attributes":{"title":"TABLE: Basic","visState":"{\"title\":\"TABLE: Basic\",\"type\":\"table\",\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"params\":{},\"schema\":\"metric\"}],\"params\":{\"perPage\":10,\"showPartialRows\":false,\"showMetricsAtAllLevels\":false,\"showTotal\":false,\"totalFunc\":\"sum\",\"percentageCol\":\"\"}}","uiStateJSON":"{}","description":"A basic table visualization","version":1,"kibanaSavedObjectMeta":{"searchSourceJSON":"{\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filter\":[],\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}"}},"references":[{"name":"kibanaSavedObjectMeta.searchSourceJSON.index","type":"index-pattern","id":"index-pattern-vis-table"}],"migrationVersion":{"visualization":"7.10.0"}}
{"exportedCount":1,"missingRefCount":0,"missingReferences":[]}
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import {
TABLE_INDEX_ID,
TABLE_INDEX_PATTERN,
TABLE_PATH_INDEX_DATA,
TABLE_INDEX_START_TIME,
TABLE_INDEX_END_TIME,
TABLE_CREATE_URL,
TABLE_VIS_APP_PATH,
TABLE_VIS_TYPE,
} from '../../../../../utils/constants';

/**
* Basic test suite description:
* Create a new table visualization from index pattern.
* Set the time range and Histogram Aggregation.
* Test that global header and side bar function correctly.
* Test that table visualization can be saved.
* Test inspector is enabled and contains correct data.
*/

describe('table visualization basic functions', () => {
before(() => {
cy.deleteIndex(TABLE_INDEX_ID);
cy.deleteIndexPattern(TABLE_INDEX_PATTERN);
cy.bulkUploadDocs(TABLE_PATH_INDEX_DATA);
cy.createIndexPattern(TABLE_INDEX_PATTERN, {
title: TABLE_INDEX_ID,
timeFieldName: 'timestamp',
});

cy.log('create a new table visualization: ', TABLE_CREATE_URL);
cy.visit(TABLE_CREATE_URL);
cy.url().should('contain', TABLE_VIS_APP_PATH);
// Select index pattern and load table visualization
cy.setTopNavDate(TABLE_INDEX_START_TIME, TABLE_INDEX_END_TIME);
// Wait for page to load
cy.waitForLoader();
});

it('Should apply changed params and allow to reset', () => {
// Set a Histogram Aggregation
cy.tbAddBucketsAggregation();
cy.tbSplitRows();
cy.tbSetupHistogramAggregation('age', '20', 2);
// Update Historgram interval
cy.tbSetHistogramInterval('201', 2);
cy.tbIsUpdateAggregationSettingsEnabled();
// Discard the updated interval
cy.tbDiscardAggregationSettings();
cy.tbIsHistogramIntervalSet('20', 2);
});

it('Should be able to save and load', () => {
const cleanupKey = Date.now();
const title = `table${cleanupKey}`;
// Save
cy.log('Save this table visualization with title ', title);
cy.getElementByTestId('visualizeSaveButton')
.should('not.be.disabled')
.click();
cy.getElementByTestId('savedObjectTitle').type(title);
cy.getElementByTestId('confirmSaveSavedObjectButton').click();
// Verify save
cy.getElementByTestId('breadcrumb last')
.invoke('attr', 'title')
.should('equal', title);
// Cleanup
cy.log('Remove saved table visualization with title ', title);
cy.deleteSavedObjectByType(TABLE_VIS_TYPE, title);
});

it('Should have inspector enabled', () => {
cy.getElementByTestId('openInspectorButton')
.invoke('attr', 'class')
.should(
'equal',
'euiButtonEmpty euiButtonEmpty--primary euiButtonEmpty--xSmall euiHeaderLink'
);
});

it('Should show correct data in inspector', () => {
const expectedData = [
'0',
'1,059',
'20',
'2,236',
'40',
'2,200',
'60',
'2,211',
'80',
'2,179',
'100',
'115',
];
cy.tbOpenInspector();
cy.tbGetTableDataFromInspectPanel().then((data) => {
expect(data).to.deep.eq(expectedData);
});
cy.tbCloseInspector();
});

after(() => {
cy.deleteIndex(TABLE_INDEX_ID);
cy.deleteIndexPattern(TABLE_INDEX_PATTERN);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,272 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import { CommonUI } from '@opensearch-dashboards-test/opensearch-dashboards-test-library';
import {
BASE_PATH,
TABLE_INDEX_ID,
TABLE_PATH_INDEX_DATA,
TABLE_INDEX_PATTERN,
TABLE_PATH_SO_DATA,
TABLE_BASIC_VIS_TITLE,
TABLE_VIS_APP_PATH,
TABLE_INDEX_START_TIME,
TABLE_INDEX_END_TIME,
toTestId,
} from '../../../../../utils/constants';

const commonUI = new CommonUI(cy);

describe('table visualization data', () => {
before(() => {
cy.deleteIndex(TABLE_INDEX_ID);
cy.deleteIndexPattern(TABLE_INDEX_PATTERN);
cy.bulkUploadDocs(TABLE_PATH_INDEX_DATA);
cy.importSavedObjects(TABLE_PATH_SO_DATA);
// Load table visualization
cy.visit(`${BASE_PATH}/app/visualize`);
cy.get('input[type="search"]').type(`${TABLE_BASIC_VIS_TITLE}{enter}`);
cy.get('.euiBasicTable-loading').should('not.exist'); // wait for the loading to stop
cy.getElementByTestId(
`visListingTitleLink-${toTestId(TABLE_BASIC_VIS_TITLE)}`
)
.should('exist')
.click();
cy.url().should('contain', TABLE_VIS_APP_PATH);
cy.setTopNavDate(TABLE_INDEX_START_TIME, TABLE_INDEX_END_TIME);
cy.waitForLoader();
});

after(() => {
cy.deleteIndex(TABLE_INDEX_ID);
cy.deleteIndexPattern(TABLE_INDEX_PATTERN);
});

describe('Check Range aggregation and Percentage Col functions', () => {
const expectedData = ['≥ 0 and < 20', '1,059', '≥ 20 and < 40', '2,236'];
const expectedAverageData = [
'≥ 0 and < 20',
'1,059',
'14.469',
'≥ 20 and < 40',
'2,236',
'29.53',
];

it('Should show correct range', () => {
cy.tbAddBucketsAggregation();
cy.tbSplitRows();
cy.tbSetupRangeAggregation(
'age',
[
['0', '20'],
['20', '40'],
],
2
);
cy.waitForLoader();
cy.tbGetTableDataFromVisualization().then((data) => {
expect(data).to.deep.eq(expectedData);
});
});

it('Should show correct average metrics', () => {
cy.tbOpenDataPanel();
cy.tbAddMetricsAggregation();
cy.tbSelectAggregationType('Average', 3);
cy.tbSelectAggregationField('age', 3);
cy.tbUpdateAggregationSettings();
cy.waitForLoader();
cy.tbGetTableDataFromVisualization().then((data) => {
expect(data).to.deep.eq(expectedAverageData);
});
});

after(() => {
cy.log('clean out all metrics and buckets aggregations');
cy.tbRemoveAllAggregations(3);
cy.tbUpdateAggregationSettings();
cy.waitForLoader();
});
});

describe('Check Average Pipeline aggregation', () => {
it('Should show correct data when using average pipeline aggregation', () => {
const expectedData = ['10,000', '128.2'];
cy.tbAddMetricsAggregation();
cy.tbSelectAggregationType('Average Bucket', 2);
cy.tbSelectSubAggregationType('Terms', 2, 'buckets');
cy.tbSelectSubAggregationField('age', 2, 'buckets');
cy.tbSelectSubAggregationType('Count', 2, 'metrics');
cy.tbUpdateAggregationSettings();
cy.waitForLoader();
cy.tbGetTableDataFromVisualization().then((data) => {
expect(data).to.deep.eq(expectedData);
});
});

after(() => {
cy.log('clean out all metrics and buckets aggregations');
cy.tbRemoveAllAggregations(2);
cy.tbUpdateAggregationSettings();
cy.waitForLoader();
});
});

describe('Check Date Histogram aggregation and filter functons', () => {
it('Should show correct data for a data table with date histogram', () => {
const expectedData = ['2021', '13', '2022', '9,987'];
cy.tbAddBucketsAggregation();
cy.tbSplitRows();
cy.tbSetupDateHistogramAggregation('timestamp', 'Year', 2);
cy.waitForLoader();
cy.tbGetTableDataFromVisualization().then((data) => {
expect(data).to.deep.eq(expectedData);
});
});

it('Should correctly filter for applied time filter on the main timefield', () => {
commonUI.addFilterRetrySelection('timestamp', 'is', '2022-05-30');
cy.waitForLoader();
cy.tbGetTableDataFromVisualization().then((data) => {
expect(data).to.deep.eq(['2022', '37']);
});
commonUI.removeFilter('timestamp');
cy.waitForLoader();
commonUI.addFilterRetrySelection('timestamp', 'is between', [
'2022-05-30',
'2022-08-30',
]);
cy.waitForLoader();
cy.tbGetTableDataFromVisualization().then((data) => {
expect(data).to.deep.eq(['2022', '3,370']);
});
});

it('Should correctly filter for pinned filters', () => {
commonUI.pinFilter('timestamp');
cy.waitForLoader();
cy.tbGetTableDataFromVisualization().then((data) => {
expect(data).to.deep.eq(['2022', '3,370']);
});
commonUI.removeFilter('timestamp');
cy.waitForLoader();
});

after(() => {
cy.log('clean out all metrics and buckets aggregations');
cy.tbRemoveAllAggregations(2);
cy.tbUpdateAggregationSettings();
cy.waitForLoader();
});
});

describe('Check Terms aggregation and missing values', () => {
it('Should show correct data before and after adding doc', () => {
cy.waitForLoader();
cy.tbGetTableDataFromVisualization().then((data) => {
expect(data).to.deep.eq(['10,000']);
});
// add a doc with missing values
cy.insertDocumentToIndex('vis-table', 10000, {
timestamp: '2022-08-30T23:20:41.280Z',
username: 'missing',
});
cy.reload();
cy.tbGetTableDataFromVisualization().then((data) => {
expect(data).to.deep.eq(['10,001']);
});
});

it('Should group data in other', () => {
const expectDataBeforeGroupInOther = [
'79',
'132',
'54',
'129',
'33',
'128',
'31',
'126',
'57',
'126',
];
const expectDataAfterGroupInOther = [
'79',
'132',
'54',
'129',
'33',
'128',
'31',
'126',
'57',
'126',
'9,359',
];
cy.tbAddBucketsAggregation();
cy.tbSplitRows();
cy.tbSetupTermsAggregation('age', 'Descending', '5', 2);
cy.waitForLoader();
cy.tbGetTableDataFromVisualization().then((data) => {
expect(data).to.deep.eq(expectDataBeforeGroupInOther);
});
cy.tbToggleOtherBucket('true');
cy.tbUpdateAggregationSettings();
cy.waitForLoader();
cy.tbGetTableDataFromVisualization().then((data) => {
expect(data).to.deep.eq(expectDataAfterGroupInOther);
});
});

it('Should include missing data', () => {
const expectDataBeforeMissing = [
'[email protected]',
'2',
'[email protected]',
'2',
'[email protected]',
'2',
'[email protected]',
'2',
'[email protected]',
'2',
'9,990',
];
const expectDataAfterMissing = [
'[email protected]',
'2',
'[email protected]',
'2',
'[email protected]',
'2',
'[email protected]',
'2',
'[email protected]',
'2',
'9,991',
];
cy.tbSelectAggregationField('email.keyword', 2);
cy.tbUpdateAggregationSettings();
cy.waitForLoader();
cy.tbGetTableDataFromVisualization().then((data) => {
expect(data).to.deep.eq(expectDataBeforeMissing);
});
cy.tbToggleMissingBucket('true');
cy.tbUpdateAggregationSettings();
cy.waitForLoader();
cy.tbGetTableDataFromVisualization().then((data) => {
expect(data).to.deep.eq(expectDataAfterMissing);
});
});

after(() => {
cy.log('clean out all metrics and buckets aggregations');
cy.tbRemoveAllAggregations(2);
cy.tbUpdateAggregationSettings();
cy.waitForLoader();
});
});
});
Loading

0 comments on commit 3dffb5f

Please sign in to comment.