OpenMetadata/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/DataQualityAndProfiler.spec.ts
Aniket Katkar 66f06fd5c6
Minor: Fix failing cypress tests in main (#17561)
* Fix Data Quality and Profiler cypress

* fix my data spec

* fix user spec failure due to user search not lisiting

* Fix for flakiness of add tier operation

* fix the customizeLanding page cypress failure

* cypress fix

---------

Co-authored-by: Chirag Madlani <12962843+chirag-madlani@users.noreply.github.com>
Co-authored-by: Ashish Gupta <ashish@getcollate.io>
Co-authored-by: Shailesh Parmar <shailesh.parmar.webdev@gmail.com>
2024-08-23 17:09:42 +05:30

1316 lines
45 KiB
TypeScript

/*
* Copyright 2022 Collate.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
descriptionBox,
interceptURL,
selectOptionFromDropdown,
toastNotification,
verifyResponseStatusCode,
} from '../../common/common';
import { createEntityTable, hardDeleteService } from '../../common/EntityUtils';
import MysqlIngestionClass from '../../common/Services/MysqlIngestionClass';
import { searchServiceFromSettingPage } from '../../common/serviceUtils';
import {
DATA_QUALITY_TEST_CASE_DATA,
prepareDataQualityTestCases,
} from '../../common/Utils/DataQuality';
import { addDomainToEntity } from '../../common/Utils/Domain';
import { visitEntityDetailsPage } from '../../common/Utils/Entity';
import {
handleIngestionRetry,
scheduleIngestion,
} from '../../common/Utils/Ingestion';
import { getToken } from '../../common/Utils/LocalStorage';
import { removeOwner, updateOwner } from '../../common/Utils/Owner';
import { goToServiceListingPage, Services } from '../../common/Utils/Services';
import {
DATA_QUALITY_SAMPLE_DATA_TABLE,
DELETE_TERM,
NEW_COLUMN_TEST_CASE,
NEW_COLUMN_TEST_CASE_WITH_NULL_TYPE,
NEW_TABLE_TEST_CASE,
NEW_TEST_SUITE,
} from '../../constants/constants';
import { EntityType, SidebarItem } from '../../constants/Entity.interface';
import { DATABASE_SERVICE } from '../../constants/EntityConstant';
import { SERVICE_CATEGORIES } from '../../constants/service.constants';
import { GlobalSettingOptions } from '../../constants/settings.constant';
const OWNER1 = 'Aaron Johnson';
const OWNER2 = 'Cynthia Meyer';
const {
testCase1,
testCase2,
filterTable,
filterTable2,
filterTableTestCases,
filterTable2TestCases,
customTable,
domainDetail,
} = DATA_QUALITY_TEST_CASE_DATA;
const TEAM_ENTITY = customTable.name;
const serviceName = DATABASE_SERVICE.service.name;
const goToProfilerTab = (data?: { service: string; entityName: string }) => {
visitEntityDetailsPage({
term: data?.entityName ?? TEAM_ENTITY,
serviceName: data?.service ?? serviceName,
entity: EntityType.Table,
});
cy.get('[data-testid="profiler"]').should('be.visible').click();
cy.get('[data-testid="profiler-tab-left-panel"]')
.contains('Table Profile')
.click();
};
const visitTestSuiteDetailsPage = (testSuiteName: string) => {
interceptURL(
'GET',
'/api/v1/dataQuality/testSuites/search/list?*testSuiteType=logical*',
'testSuite'
);
interceptURL('GET', '/api/v1/dataQuality/testCases?fields=*', 'testCase');
cy.sidebarClick(SidebarItem.DATA_QUALITY);
cy.get('[data-testid="by-test-suites"]').click();
verifyResponseStatusCode('@testSuite', 200);
interceptURL(
'GET',
`/api/v1/dataQuality/testSuites/search/list?*${testSuiteName}*testSuiteType=logical*`,
'testSuiteBySearch'
);
cy.get('[data-testid="search-bar-container"]').type(testSuiteName);
verifyResponseStatusCode('@testSuiteBySearch', 200);
cy.get(`[data-testid="${testSuiteName}"]`).scrollIntoView().click();
};
const verifyFilterTestCase = () => {
filterTableTestCases.map((testCase) => {
cy.get(`[data-testid="${testCase}"]`).scrollIntoView().should('be.visible');
});
};
const verifyFilter2TestCase = (negation = false) => {
filterTable2TestCases.map((testCase) => {
negation
? cy.get(`[data-testid="${testCase}"]`).should('not.exist')
: cy
.get(`[data-testid="${testCase}"]`)
.scrollIntoView()
.should('be.visible');
});
};
describe(
'Data Quality and Profiler should work properly',
{ tags: 'Observability' },
() => {
const mySql = new MysqlIngestionClass();
before(() => {
cy.login();
cy.getAllLocalStorage().then((data) => {
const token = getToken(data);
createEntityTable({
token,
...DATABASE_SERVICE,
tables: [
DATABASE_SERVICE.entity,
filterTable,
filterTable2,
customTable,
],
});
prepareDataQualityTestCases(token);
});
});
after(() => {
cy.login();
cy.getAllLocalStorage().then((data) => {
const token = getToken(data);
hardDeleteService({
token,
serviceFqn: DATABASE_SERVICE.service.name,
serviceType: SERVICE_CATEGORIES.DATABASE_SERVICES,
});
});
});
beforeEach(() => {
cy.login();
interceptURL('GET', `/api/v1/tables/*/systemProfile?*`, 'systemProfile');
interceptURL('GET', `/api/v1/tables/*/tableProfile?*`, 'tableProfile');
});
it('Add and ingest mysql data', () => {
goToServiceListingPage(Services.Database);
mySql.createService();
});
it('Add Profiler ingestion', () => {
const data = {
entityName: 'alert_entity',
service: 'cypress%mysql',
};
interceptURL(
'POST',
'/api/v1/services/ingestionPipelines/deploy/*',
'deployIngestion'
);
goToProfilerTab(data);
cy.get('[data-testid="no-profiler-placeholder"]').should('be.visible');
cy.clickOnLogo();
cy.settingClick(GlobalSettingOptions.DATABASES);
cy.intercept('/api/v1/services/ingestionPipelines?*').as('ingestionData');
searchServiceFromSettingPage(data.service);
cy.get(`[data-testid="service-name-${data.service}"]`)
.should('exist')
.click();
cy.get('[data-testid="tabs"]').should('exist');
cy.wait('@ingestionData');
cy.get('[data-testid="ingestions"]')
.scrollIntoView()
.should('be.visible')
.click();
cy.get('[data-testid="ingestion-details-container"]').should('exist');
cy.get('[data-testid="add-new-ingestion-button"]')
.should('be.visible')
.click();
cy.get('[data-menu-id*="profiler"')
.scrollIntoView()
.contains('Profiler Ingestion')
.click();
cy.get('#root\\/profileSample')
.scrollIntoView()
.should('be.visible')
.and('not.be.disabled')
.type('10');
cy.get('[data-testid="submit-btn"]')
.scrollIntoView()
.should('be.visible')
.click();
scheduleIngestion(false);
cy.wait('@deployIngestion').then(() => {
cy.get('[data-testid="view-service-button"]')
.scrollIntoView()
.should('be.visible')
.click();
handleIngestionRetry(0, 'profiler');
});
});
it('Verifying profiler ingestion', () => {
goToProfilerTab({
entityName: 'alert_entity',
service: 'cypress%mysql',
});
cy.get('[data-testid="no-profiler-placeholder"]').should('not.exist');
});
it('Add table test case', () => {
goToProfilerTab();
interceptURL(
'GET',
`api/v1/tables/name/${serviceName}.*.${TEAM_ENTITY}?include=all`,
'addTableTestPage'
);
verifyResponseStatusCode('@systemProfile', 200);
verifyResponseStatusCode('@tableProfile', 200);
interceptURL('GET', '/api/v1/dataQuality/testCases?fields=*', 'testCase');
cy.get('[data-testid="profiler-tab-left-panel"]')
.contains('Data Quality')
.click();
verifyResponseStatusCode('@testCase', 200);
cy.get('[data-testid="profiler-add-table-test-btn"]').click();
cy.get('[data-testid="table"]').click();
// creating new test case
cy.get('#tableTestForm_testTypeId').scrollIntoView().click();
cy.contains(NEW_TABLE_TEST_CASE.label).should('be.visible').click();
cy.get('#tableTestForm_testName').type(NEW_TABLE_TEST_CASE.name);
cy.get('#tableTestForm_params_columnName').type(
NEW_TABLE_TEST_CASE.field
);
cy.get(descriptionBox).scrollIntoView();
cy.get(descriptionBox).type(NEW_TABLE_TEST_CASE.description);
cy.get('[data-testid="submit-test"]')
.scrollIntoView()
.should('be.visible')
.click();
cy.get('[data-testid="success-line"]')
.scrollIntoView()
.should('be.visible');
cy.get('[data-testid="add-ingestion-button"]')
.should('be.visible')
.click();
cy.get('[data-testid="select-all-test-cases"]').click();
scheduleIngestion(false);
cy.get('[data-testid="success-line"]')
.scrollIntoView()
.should('be.visible');
cy.get('[data-testid="view-service-button"]')
.should('be.visible')
.click({ force: true });
verifyResponseStatusCode('@getEntityDetails', 200);
cy.get('[data-testid="profiler-tab-left-panel"]')
.contains('Data Quality')
.click();
verifyResponseStatusCode('@testCase', 200);
cy.contains(NEW_TABLE_TEST_CASE.name).should('be.visible');
});
it('Edit table test case', () => {
goToProfilerTab();
cy.get('[data-testid="profiler-tab-left-panel"]')
.contains('Data Quality')
.click();
cy.get(`[data-testid="${NEW_TABLE_TEST_CASE.name}"]`).should(
'be.visible'
);
cy.get(`[data-testid="edit-${NEW_TABLE_TEST_CASE.name}"]`).click();
cy.get('#tableTestForm_params_columnName')
.scrollIntoView()
.clear()
.type('test');
interceptURL('PATCH', '/api/v1/dataQuality/testCases/*', 'updateTest');
cy.get('.ant-modal-footer').contains('Submit').click();
verifyResponseStatusCode('@updateTest', 200);
cy.get('.Toastify__toast-body')
.contains('Test case updated successfully.')
.should('be.visible');
cy.get(`[data-testid="edit-${NEW_TABLE_TEST_CASE.name}"]`).click();
cy.get('#tableTestForm_params_columnName').should('have.value', 'test');
});
it('Add Column test case with min max params', () => {
goToProfilerTab();
interceptURL(
'GET',
`api/v1/tables/name/${serviceName}.*.${TEAM_ENTITY}?include=all`,
'addTableTestPage'
);
verifyResponseStatusCode('@systemProfile', 200);
verifyResponseStatusCode('@tableProfile', 200);
interceptURL('GET', '/api/v1/dataQuality/testCases?fields=*', 'testCase');
cy.get('[data-testid="profiler-tab-left-panel"]')
.contains('Data Quality')
.click();
verifyResponseStatusCode('@testCase', 200);
cy.get('[data-testid="profiler-add-table-test-btn"]').click();
cy.get('[data-testid="column"]').click();
// creating new test case
cy.get('#tableTestForm_column').click();
cy.get(`[title="${NEW_COLUMN_TEST_CASE.column}"]`)
.scrollIntoView()
.click();
cy.get('#tableTestForm_testName').type(NEW_COLUMN_TEST_CASE.name);
cy.get('#tableTestForm_testTypeId').scrollIntoView().click();
cy.get(`[title="${NEW_COLUMN_TEST_CASE.label}"]`)
.scrollIntoView()
.click();
cy.get('#tableTestForm_params_minLength')
.scrollIntoView()
.type(NEW_COLUMN_TEST_CASE.min);
cy.get('#tableTestForm_params_maxLength')
.scrollIntoView()
.type(NEW_COLUMN_TEST_CASE.max);
cy.get(descriptionBox)
.scrollIntoView()
.type(NEW_COLUMN_TEST_CASE.description);
cy.get('[data-testid="submit-test"]').scrollIntoView().click();
cy.get('[data-testid="success-line"]')
.scrollIntoView()
.contains(
'has been created successfully. This will be picked up in the next run.'
)
.should('be.visible');
cy.get('[data-testid="view-service-button"]').scrollIntoView().click();
cy.get('[data-testid="profiler-tab-left-panel"]')
.contains('Data Quality')
.click();
cy.contains(NEW_COLUMN_TEST_CASE.name)
.scrollIntoView()
.should('be.visible');
});
it('Add column test case for columnValuesToBeNotNull', () => {
// Creating new test case and selecting Null team type
goToProfilerTab();
interceptURL(
'GET',
`api/v1/tables/name/${serviceName}.*.${TEAM_ENTITY}?include=all`,
'addTableTestPage'
);
verifyResponseStatusCode('@systemProfile', 200);
verifyResponseStatusCode('@tableProfile', 200);
interceptURL('GET', '/api/v1/dataQuality/testCases?fields=*', 'testCase');
cy.get('[data-testid="profiler-tab-left-panel"]')
.contains('Data Quality')
.click();
verifyResponseStatusCode('@testCase', 200);
cy.get('[data-testid="profiler-add-table-test-btn"]').click();
cy.get('[data-testid="column"]').click();
cy.get('#tableTestForm_column').click();
cy.get(`[title="${NEW_COLUMN_TEST_CASE_WITH_NULL_TYPE.column}"]`)
.scrollIntoView()
.click();
cy.get('#tableTestForm_testName').type(
NEW_COLUMN_TEST_CASE_WITH_NULL_TYPE.name
);
cy.get('#tableTestForm_testTypeId').type(
NEW_COLUMN_TEST_CASE_WITH_NULL_TYPE.type
);
cy.get(`[title="${NEW_COLUMN_TEST_CASE_WITH_NULL_TYPE.label}"]`).click();
cy.get(descriptionBox)
.scrollIntoView()
.type(NEW_COLUMN_TEST_CASE_WITH_NULL_TYPE.description);
cy.get('[data-testid="submit-test"]').scrollIntoView().click();
cy.get('[data-testid="success-line"]')
.contains(
'has been created successfully. This will be picked up in the next run.'
)
.should('be.visible');
cy.get('[data-testid="view-service-button"]').scrollIntoView().click();
cy.get('[data-testid="profiler-tab-left-panel"]')
.contains('Data Quality')
.click();
cy.get(
`[data-testid="${NEW_COLUMN_TEST_CASE_WITH_NULL_TYPE.name}"]`
).should('contain', NEW_COLUMN_TEST_CASE_WITH_NULL_TYPE.name);
});
it('Edit column test case should work properly', () => {
interceptURL('GET', '/api/v1/dataQuality/testCases?*', 'testCase');
goToProfilerTab();
cy.get('[data-testid="profiler-tab-left-panel"]')
.contains('Data Quality')
.click();
verifyResponseStatusCode('@testCase', 200);
cy.get(`[data-testid="${NEW_COLUMN_TEST_CASE.name}"]`).should(
'be.visible'
);
cy.get(`[data-testid="edit-${NEW_COLUMN_TEST_CASE.name}"]`)
.scrollIntoView()
.should('be.visible')
.click();
cy.get('#tableTestForm_params_minLength')
.scrollIntoView()
.should('be.visible')
.clear()
.type('4');
interceptURL('PATCH', '/api/v1/dataQuality/testCases/*', 'updateTest');
cy.get('.ant-modal-footer').contains('Submit').click();
verifyResponseStatusCode('@updateTest', 200);
cy.get('.Toastify__toast-body')
.contains('Test case updated successfully.')
.should('be.visible');
cy.get(`[data-testid="edit-${NEW_COLUMN_TEST_CASE.name}"]`).click();
cy.get('#tableTestForm_params_minLength').should('have.value', '4');
cy.get('.ant-modal-footer').contains('Cancel').click();
// Editing Non Team Type Test Case
cy.get(
`[data-testid="${NEW_COLUMN_TEST_CASE_WITH_NULL_TYPE.name}"]`
).should('be.visible');
cy.get(`[data-testid="edit-${NEW_COLUMN_TEST_CASE_WITH_NULL_TYPE.name}"]`)
.scrollIntoView()
.should('be.visible')
.click();
cy.get('.ant-modal-footer').contains('Cancel').click();
});
it('Delete Column Test Case should work properly', () => {
interceptURL('GET', '/api/v1/dataQuality/testCases?*', 'testCase');
goToProfilerTab();
cy.get('[data-testid="profiler-tab-left-panel"]')
.contains('Data Quality')
.should('be.visible')
.click();
verifyResponseStatusCode('@testCase', 200);
[NEW_COLUMN_TEST_CASE.name, NEW_COLUMN_TEST_CASE_WITH_NULL_TYPE.name].map(
(test) => {
cy.get(`[data-testid="${test}"]`)
.scrollIntoView()
.should('be.visible');
cy.get(`[data-testid="delete-${test}"]`).scrollIntoView().click();
cy.get('[data-testid="hard-delete-option"]').click();
cy.get('[data-testid="confirmation-text-input"]').type(DELETE_TERM);
interceptURL(
'DELETE',
'/api/v1/dataQuality/testCases/*?hardDelete=true&recursive=true',
'deleteTest'
);
interceptURL('GET', '/api/v1/dataQuality/testCases?*', 'getTestCase');
cy.get('[data-testid="confirm-button"]').click();
verifyResponseStatusCode('@deleteTest', 200);
verifyResponseStatusCode('@getTestCase', 200);
toastNotification(`"${test}" deleted successfully!`);
}
);
});
it('Create logical test suite', () => {
const testCaseName = 'column_value_max_to_be_between';
interceptURL(
'GET',
'/api/v1/dataQuality/testSuites/search/list?*testSuiteType=logical*',
'testSuite'
);
interceptURL(
'GET',
'/api/v1/search/query?q=*&index=test_case_search_index*',
'getTestCase'
);
cy.sidebarClick(SidebarItem.DATA_QUALITY);
cy.get('[data-testid="by-test-suites"]').click();
verifyResponseStatusCode('@testSuite', 200);
cy.get('[data-testid="add-test-suite-btn"]').click();
// creating test suite
cy.get('[data-testid="test-suite-name"]').type(NEW_TEST_SUITE.name);
cy.get(descriptionBox).scrollIntoView().type(NEW_TEST_SUITE.description);
cy.get('[data-testid="submit-button"]').click();
cy.get('[data-testid="searchbar"]').type(testCaseName);
verifyResponseStatusCode('@getTestCase', 200);
cy.get(`[data-testid="${testCaseName}"]`).scrollIntoView().as('testCase');
cy.get('@testCase').click();
cy.get('[data-testid="submit"]').scrollIntoView().click();
cy.get('[data-testid="success-line"]').should(
'contain',
'has been created successfully'
);
});
it('User as Owner assign, update & delete for test suite', () => {
interceptURL(
'GET',
'/api/v1/search/query?q=*&index=test_case_search_index*',
'searchTestCase'
);
interceptURL('GET', '/api/v1/dataQuality/testCases?fields=*', 'testCase');
interceptURL(
'PUT',
'/api/v1/dataQuality/testCases/logicalTestCases',
'putTestCase'
);
visitTestSuiteDetailsPage(NEW_TEST_SUITE.name);
updateOwner(OWNER2);
removeOwner(OWNER2);
updateOwner(OWNER1);
});
it('Add test case to logical test suite', () => {
const testCaseName = 'column_values_to_be_between';
interceptURL(
'GET',
'/api/v1/search/query?q=*&index=test_case_search_index*',
'searchTestCase'
);
interceptURL('GET', '/api/v1/dataQuality/testCases?fields=*', 'testCase');
interceptURL(
'PUT',
'/api/v1/dataQuality/testCases/logicalTestCases',
'putTestCase'
);
visitTestSuiteDetailsPage(NEW_TEST_SUITE.name);
cy.get('[data-testid="add-test-case-btn"]').click();
verifyResponseStatusCode('@testCase', 200);
cy.get('[data-testid="searchbar"]').type(testCaseName);
verifyResponseStatusCode('@searchTestCase', 200);
cy.get(`[data-testid="${testCaseName}"]`)
.scrollIntoView()
.as('newTestCase');
cy.get('@newTestCase').click();
cy.get('[data-testid="submit"]').scrollIntoView().click();
verifyResponseStatusCode('@putTestCase', 200);
});
it('Remove test case from logical test suite', () => {
interceptURL('GET', '/api/v1/dataQuality/testCases?fields=*', 'testCase');
interceptURL(
'GET',
'/api/v1/permissions/testSuite/name/mysql_matrix',
'testSuitePermission'
);
interceptURL(
'DELETE',
'/api/v1/dataQuality/testCases/logicalTestCases/*/*',
'removeTestCase'
);
visitTestSuiteDetailsPage(NEW_TEST_SUITE.name);
verifyResponseStatusCode('@testSuitePermission', 200);
verifyResponseStatusCode('@testCase', 200);
cy.get('[data-testid="remove-column_values_to_be_between"]').click();
cy.get('[data-testid="save-button"]').click();
verifyResponseStatusCode('@removeTestCase', 200);
cy.get('[data-testid="remove-column_value_max_to_be_between"]').click();
cy.get('[data-testid="save-button"]').click();
verifyResponseStatusCode('@removeTestCase', 200);
});
it('Test suite filters', () => {
interceptURL(
'GET',
'/api/v1/dataQuality/testSuites/search/list?*testSuiteType=logical*',
'testSuite'
);
interceptURL(
'GET',
'/api/v1/dataQuality/testSuites/search/list?*owner=*',
'testSuiteByOwner'
);
cy.sidebarClick(SidebarItem.DATA_QUALITY);
cy.get('[data-testid="by-test-suites"]').click();
verifyResponseStatusCode('@testSuite', 200);
interceptURL('GET', '/api/v1/users?*isBot=false*', 'getOwner');
// owner filter
cy.get('[data-testid="owner-select-filter"]').click();
cy.get("[data-testid='select-owner-tabs']").should('be.visible');
cy.get('.ant-tabs [id*=tab-users]').click();
cy.wait('@getOwner');
interceptURL(
'GET',
`api/v1/search/query?q=*&index=user_search_index*`,
'searchOwner'
);
cy.get('[data-testid="owner-select-users-search-bar"]').type(OWNER1);
verifyResponseStatusCode('@searchOwner', 200);
cy.get(`.ant-popover [title="${OWNER1}"]`).click();
verifyResponseStatusCode('@testSuiteByOwner', 200);
cy.get(`[data-testid="${NEW_TEST_SUITE.name}"]`)
.scrollIntoView()
.should('be.visible');
});
it('Delete test suite', () => {
visitTestSuiteDetailsPage(NEW_TEST_SUITE.name);
cy.get('[data-testid="manage-button"]').should('be.visible').click();
cy.get('[data-testid="delete-button"]').should('be.visible').click();
// Click on Permanent/Hard delete option
cy.get('[data-testid="hard-delete-option"]')
.should('contain', NEW_TEST_SUITE.name)
.should('be.visible')
.click();
cy.get('[data-testid="confirm-button"]')
.should('exist')
.should('be.disabled');
cy.get('[data-testid="confirmation-text-input"]')
.should('be.visible')
.type(DELETE_TERM);
interceptURL(
'DELETE',
'/api/v1/dataQuality/testSuites/*?hardDelete=true&recursive=true',
'deleteTestSuite'
);
cy.get('[data-testid="confirm-button"]')
.should('be.visible')
.should('not.be.disabled')
.click();
verifyResponseStatusCode('@deleteTestSuite', 200);
toastNotification('"mysql_matrix" deleted successfully!');
});
it('delete created service', () => {
goToServiceListingPage(Services.Database);
mySql.deleteService();
});
it('Profiler matrix and test case graph should visible', () => {
const { term, entity, serviceName, testCaseName } =
DATA_QUALITY_SAMPLE_DATA_TABLE;
visitEntityDetailsPage({ term, serviceName, entity });
cy.get('[data-testid="entity-header-display-name"]')
.contains(term)
.should('be.visible');
cy.get('[data-testid="profiler"]').should('be.visible').click();
cy.get('[data-testid="profiler-tab-left-panel"]')
.contains('Table Profile')
.click();
interceptURL(
'GET',
'/api/v1/tables/*/columnProfile?*',
'getProfilerInfo'
);
interceptURL('GET', '/api/v1/dataQuality/testCases?*', 'getTestCaseInfo');
cy.get('[data-testid="profiler-tab-left-panel"]')
.contains('Column Profile')
.click();
cy.get('[data-row-key="shop_id"]')
.contains('shop_id')
.scrollIntoView()
.click();
verifyResponseStatusCode('@getProfilerInfo', 200);
verifyResponseStatusCode('@getTestCaseInfo', 200);
cy.get('#count_graph').scrollIntoView().should('be.visible');
cy.get('#proportion_graph').scrollIntoView().should('be.visible');
cy.get('#math_graph').scrollIntoView().should('be.visible');
cy.get('#sum_graph').scrollIntoView().should('be.visible');
interceptURL(
'GET',
'/api/v1/dataQuality/testCases/name/*?fields=*',
'getTestCaseDetails'
);
interceptURL(
'GET',
'/api/v1/dataQuality/testCases/*/testCaseResult?*',
'getTestResult'
);
cy.get('[data-testid="profiler-tab-left-panel"]')
.contains('Data Quality')
.click();
cy.get(`[data-testid="${testCaseName}"]`).contains(testCaseName).click();
verifyResponseStatusCode('@getTestCaseDetails', 200);
cy.wait('@getTestResult').then(() => {
cy.get(`[id="${testCaseName}_graph"]`)
.scrollIntoView()
.should('be.visible');
});
});
it('Array params value should be visible while editing the test case', () => {
const tableName = DATABASE_SERVICE.entity.name;
goToProfilerTab({
service: DATABASE_SERVICE.service.name,
entityName: tableName,
});
interceptURL('GET', '/api/v1/dataQuality/testCases?fields=*', 'testCase');
interceptURL(
'GET',
'/api/v1/dataQuality/testDefinitions/*',
'testCaseDefinition'
);
cy.get('[data-testid="profiler-tab-left-panel"]')
.contains('Data Quality')
.click();
verifyResponseStatusCode('@testCase', 200);
cy.get(`[data-testid="${testCase2.name}"]`)
.scrollIntoView()
.should('be.visible');
cy.get(`[data-testid="edit-${testCase2.name}"]`)
.should('be.visible')
.click();
verifyResponseStatusCode('@testCaseDefinition', 200);
cy.get('#tableTestForm_params_allowedValues_0_value')
.scrollIntoView()
.should('have.value', 'gmail');
cy.get('#tableTestForm_params_allowedValues_1_value')
.scrollIntoView()
.should('have.value', 'yahoo');
cy.get('#tableTestForm_params_allowedValues_2_value')
.scrollIntoView()
.should('have.value', 'collate');
});
it('Validate patch request for edit test case', () => {
const tableName = DATABASE_SERVICE.entity.name;
goToProfilerTab({
service: DATABASE_SERVICE.service.name,
entityName: tableName,
});
interceptURL(
'PATCH',
'/api/v1/dataQuality/testCases/*',
'updateTestCase'
);
interceptURL('GET', '/api/v1/dataQuality/testCases?fields=*', 'testCase');
interceptURL(
'GET',
'/api/v1/dataQuality/testDefinitions/*',
'testCaseDefinition'
);
cy.get('[data-testid="profiler-tab-left-panel"]')
.contains('Data Quality')
.click();
verifyResponseStatusCode('@testCase', 200);
cy.get(`[data-testid="edit-${testCase2.name}"]`).scrollIntoView().click();
verifyResponseStatusCode('@testCaseDefinition', 200);
cy.get('#tableTestForm_displayName').type('Table test case display name');
cy.get('#tableTestForm_table').should(
'have.value',
DATABASE_SERVICE.entity.name
);
cy.get('#tableTestForm_column').should('have.value', 'email');
cy.get('#tableTestForm_name').should('have.value', testCase2.name);
cy.get('#tableTestForm_testDefinition').should(
'have.value',
'Column Values To Be In Set'
);
cy.get('.ant-modal-footer').contains('Submit').click();
cy.wait('@updateTestCase').then((interception) => {
const { body } = interception.request;
expect(body).to.deep.equal([
{
op: 'add',
path: '/displayName',
value: 'Table test case display name',
},
]);
});
cy.get(`[data-testid="edit-${testCase2.name}"]`).scrollIntoView().click();
cy.get('#tableTestForm_params_allowedValues_0_value')
.scrollIntoView()
.clear()
.type('test');
cy.get('.ant-modal-footer').contains('Submit').click();
cy.wait('@updateTestCase').then((interception) => {
const { body } = interception.request;
expect(body).to.deep.equal([
{
op: 'replace',
path: '/parameterValues/0/value',
value: '["test","yahoo","collate"]',
},
]);
});
cy.get(`[data-testid="edit-${testCase2.name}"]`).scrollIntoView().click();
cy.get(descriptionBox).scrollIntoView().type('Test case description');
cy.get('.ant-modal-footer').contains('Submit').click();
cy.wait('@updateTestCase').then((interception) => {
const { body } = interception.request;
expect(body).to.deep.equal([
{ op: 'add', path: '/description', value: 'Test case description' },
]);
});
});
it('Update displayName of test case', () => {
interceptURL(
'GET',
'/api/v1/dataQuality/testCases/search/list?*',
'getTestCase'
);
cy.sidebarClick(SidebarItem.DATA_QUALITY);
cy.get('[data-testid="by-test-cases"]').click();
verifyResponseStatusCode('@getTestCase', 200);
interceptURL(
'GET',
`/api/v1/dataQuality/testCases/search/list?*q=*${testCase1.name}*`,
'searchTestCase'
);
cy.get(
'[data-testid="test-case-container"] [data-testid="searchbar"]'
).type(testCase1.name);
verifyResponseStatusCode('@searchTestCase', 200);
cy.get(`[data-testid="${testCase1.name}"]`)
.scrollIntoView()
.should('be.visible');
cy.get(`[data-testid="edit-${testCase1.name}"]`).click();
cy.get('.ant-modal-body').should('be.visible');
cy.get('#tableTestForm_displayName').type('Table test case display name');
interceptURL(
'PATCH',
'/api/v1/dataQuality/testCases/*',
'updateTestCase'
);
cy.get('.ant-modal-footer').contains('Submit').click();
verifyResponseStatusCode('@updateTestCase', 200);
cy.get(`[data-testid="${testCase1.name}"]`)
.scrollIntoView()
.invoke('text')
.then((text) => {
expect(text).to.eq('Table test case display name');
});
});
it('Test case filters', () => {
interceptURL(
'GET',
'/api/v1/dataQuality/testCases/search/list?*',
'getTestCase'
);
interceptURL(
'GET',
`/api/v1/search/query?q=*index=tag_search_index*`,
'searchTags'
);
cy.sidebarClick(SidebarItem.DATA_QUALITY);
cy.get('[data-testid="by-test-cases"]').click();
verifyResponseStatusCode('@getTestCase', 200);
interceptURL(
'GET',
`/api/v1/dataQuality/testCases/search/list?*q=*${filterTableTestCases[0]}*`,
'searchTestCase'
);
cy.get('[data-testid="advanced-filter"]').click({
waitForAnimations: true,
});
cy.get('[value="tableFqn"]').click({ waitForAnimations: true });
cy.get('[data-testid="advanced-filter"]').click({
waitForAnimations: true,
});
cy.get('[value="testPlatforms"]').click({ waitForAnimations: true });
cy.get('[data-testid="advanced-filter"]').click({
waitForAnimations: true,
});
cy.get('[value="lastRunRange"]').click({ waitForAnimations: true });
cy.get('[data-testid="advanced-filter"]').click({
waitForAnimations: true,
});
cy.get('[value="serviceName"]').click({ waitForAnimations: true });
cy.get('[data-testid="advanced-filter"]').click({
waitForAnimations: true,
});
cy.get('[value="tags"]').click({ waitForAnimations: true });
cy.get('[data-testid="advanced-filter"]').click({
waitForAnimations: true,
});
cy.get('[value="tier"]').click({ waitForAnimations: true });
// Test case search filter
cy.get(
'[data-testid="test-case-container"] [data-testid="searchbar"]'
).type(filterTableTestCases[0]);
verifyResponseStatusCode('@searchTestCase', 200);
cy.get(`[data-testid="${filterTableTestCases[0]}"]`)
.scrollIntoView()
.should('be.visible');
cy.get('.ant-input-clear-icon').click();
verifyResponseStatusCode('@getTestCase', 200);
// Test case filter by service name
interceptURL(
'GET',
`/api/v1/dataQuality/testCases/search/list?*serviceName=${DATABASE_SERVICE.service.name}*`,
'getTestCaseByServiceName'
);
interceptURL(
'GET',
`/api/v1/search/query?q=*index=database_service_search_index*`,
'searchService'
);
cy.get('#serviceName')
.scrollIntoView()
.type(DATABASE_SERVICE.service.name);
verifyResponseStatusCode('@searchService', 200);
cy.get('.ant-select-dropdown')
.not('.ant-select-dropdown-hidden')
.find(`[data-testid="${DATABASE_SERVICE.service.name}"]`)
.click({ force: true });
verifyResponseStatusCode('@getTestCaseByServiceName', 200);
verifyFilterTestCase();
verifyFilter2TestCase();
// remove service filter
cy.get('[data-testid="advanced-filter"]').click({
waitForAnimations: true,
});
cy.get('[value="serviceName"]').click({ waitForAnimations: true });
verifyResponseStatusCode('@getTestCase', 200);
cy.get('#serviceName').should('not.exist');
// Test case filter by Tags
interceptURL(
'GET',
`/api/v1/dataQuality/testCases/search/list?*tags=${'PII.None'}*`,
'getTestCaseByTags'
);
cy.get('#tags').scrollIntoView().click().type('PII.None');
verifyResponseStatusCode('@searchTags', 200);
cy.get('.ant-select-dropdown')
.not('.ant-select-dropdown-hidden')
.find(`[data-testid="${'PII.None'}"]`)
.click({ force: true });
verifyResponseStatusCode('@getTestCaseByTags', 200);
verifyFilterTestCase();
verifyFilter2TestCase(true);
// remove tags filter
cy.get('[data-testid="advanced-filter"]').click({
waitForAnimations: true,
});
cy.get('[value="tags"]').click({ waitForAnimations: true });
verifyResponseStatusCode('@getTestCase', 200);
cy.get('#tags').should('not.exist');
// Test case filter by Tier
interceptURL(
'GET',
`/api/v1/dataQuality/testCases/search/list?*tier=${'Tier.Tier2'}*`,
'getTestCaseByTier'
);
cy.get('#tier').click();
cy.get('.ant-select-dropdown')
.not('.ant-select-dropdown-hidden')
.find(`[data-testid="${'Tier.Tier2'}"]`)
.click({ force: true });
verifyResponseStatusCode('@getTestCaseByTier', 200);
verifyFilterTestCase();
verifyFilter2TestCase(true);
// remove tier filter
cy.get('[data-testid="advanced-filter"]').click({
waitForAnimations: true,
});
cy.get('[value="tier"]').click({ waitForAnimations: true });
verifyResponseStatusCode('@getTestCase', 200);
cy.get('#tier').should('not.exist');
// Test case filter by table name
interceptURL(
'GET',
`/api/v1/dataQuality/testCases/search/list?*entityLink=*${filterTable.name}*`,
'searchTestCaseByTable'
);
interceptURL(
'GET',
`/api/v1/search/query?q=*index=table_search_index*`,
'searchTable'
);
cy.get('#tableFqn').scrollIntoView().type(filterTable.name);
verifyResponseStatusCode('@searchTable', 200);
cy.get('.ant-select-dropdown')
.not('.ant-select-dropdown-hidden')
.find(
`[data-testid="${filterTable.databaseSchema}.${filterTable.name}"]`
)
.click({ force: true });
verifyResponseStatusCode('@searchTestCaseByTable', 200);
verifyFilterTestCase();
verifyFilter2TestCase(true);
// Test case filter by test type
interceptURL(
'GET',
`/api/v1/dataQuality/testCases/search/list?*testCaseType=column*`,
'testCaseTypeByColumn'
);
cy.get('[data-testid="test-case-type-select-filter"]').click();
selectOptionFromDropdown('Column');
verifyResponseStatusCode('@testCaseTypeByColumn', 200);
cy.get('[data-testid="search-error-placeholder"]').should('be.visible');
interceptURL(
'GET',
`/api/v1/dataQuality/testCases/search/list?*testCaseType=table*`,
'testCaseTypeByTable'
);
cy.get('[data-testid="test-case-type-select-filter"]').click();
selectOptionFromDropdown('Table');
verifyResponseStatusCode('@testCaseTypeByTable', 200);
verifyFilterTestCase();
cy.get('[data-testid="test-case-type-select-filter"]').click();
selectOptionFromDropdown('All');
verifyResponseStatusCode('@getTestCase', 200);
// Test case filter by status
interceptURL(
'GET',
`/api/v1/dataQuality/testCases/search/list?*testCaseStatus=Success*`,
'testCaseStatusBySuccess'
);
cy.get('[data-testid="status-select-filter"]').click();
selectOptionFromDropdown('Success');
verifyResponseStatusCode('@testCaseStatusBySuccess', 200);
cy.get('[data-testid="search-error-placeholder"]').should('be.visible');
interceptURL(
'GET',
`/api/v1/dataQuality/testCases/search/list?*testCaseStatus=Failed*`,
'testCaseStatusByFailed'
);
cy.get('[data-testid="status-select-filter"]').click();
selectOptionFromDropdown('Failed');
verifyResponseStatusCode('@testCaseStatusByFailed', 200);
verifyFilterTestCase();
// Test case filter by platform
interceptURL(
'GET',
`/api/v1/dataQuality/testCases/search/list?*testPlatforms=DBT*`,
'testCasePlatformByDBT'
);
cy.get('[data-testid="platform-select-filter"]').click();
selectOptionFromDropdown('DBT');
verifyResponseStatusCode('@testCasePlatformByDBT', 200);
cy.clickOutside();
cy.get('[data-testid="search-error-placeholder"]').should('be.visible');
cy.get(
'[data-testid="platform-select-filter"] .ant-select-clear'
).click();
verifyResponseStatusCode('@getTestCase', 200);
interceptURL(
'GET',
`/api/v1/dataQuality/testCases/search/list?*testPlatforms=OpenMetadata*`,
'testCasePlatformByOpenMetadata'
);
cy.get('[data-testid="platform-select-filter"]').click();
selectOptionFromDropdown('OpenMetadata');
verifyResponseStatusCode('@testCasePlatformByOpenMetadata', 200);
cy.clickOutside();
verifyFilterTestCase();
cy.url().then((url) => {
cy.reload();
verifyResponseStatusCode('@testCasePlatformByOpenMetadata', 200);
cy.url().then((updatedUrl) => {
expect(url).to.be.equal(updatedUrl);
});
});
cy.get('[data-testid="advanced-filter"]').click({
waitForAnimations: true,
});
cy.get('[value="testPlatforms"]').click({
waitForAnimations: true,
});
verifyResponseStatusCode('@getTestCase', 200);
cy.get('[value="platform-select-filter"]').should('not.exist');
cy.reload();
verifyResponseStatusCode('@getTestCase', 200);
cy.get('[value="tier"]').should('not.exist');
});
it('Filter with domain', () => {
visitEntityDetailsPage({
term: filterTable.name,
serviceName: serviceName,
entity: EntityType.Table,
});
addDomainToEntity(domainDetail.name);
interceptURL(
'GET',
'/api/v1/dataQuality/testCases/search/list?*',
'getTestCase'
);
cy.get('[data-testid="domain-dropdown"]').click();
cy.get(`li[data-menu-id*='${domainDetail.name}']`).click();
cy.sidebarClick(SidebarItem.DATA_QUALITY);
cy.get('[data-testid="by-test-cases"]').click();
verifyResponseStatusCode('@getTestCase', 200);
cy.get('[data-testid="advanced-filter"]').click({
waitForAnimations: true,
});
cy.get('[value="tableFqn"]').click({ waitForAnimations: true });
// Test case filter by table name
interceptURL(
'GET',
`/api/v1/dataQuality/testCases/search/list?*entityLink=*${filterTable.name}*`,
'searchTestCaseByTable'
);
cy.get('#tableFqn').scrollIntoView().type(filterTable.name);
cy.get('.ant-select-dropdown')
.not('.ant-select-dropdown-hidden')
.find(
`[data-testid="${filterTable.databaseSchema}.${filterTable.name}"]`
)
.click({ force: true });
verifyResponseStatusCode('@searchTestCaseByTable', 200);
verifyFilterTestCase();
});
it('Update profiler setting modal', () => {
const profilerSetting = {
profileSample: '60',
sampleDataCount: '100',
profileQuery: 'select * from table',
excludeColumns: 'user_id',
includeColumns: 'shop_id',
partitionColumnName: 'name',
partitionIntervalType: 'COLUMN-VALUE',
partitionValues: 'test',
};
interceptURL(
'GET',
'/api/v1/tables/*/tableProfile?startTs=*',
'tableProfiler'
);
interceptURL('GET', '/api/v1/tables/*/systemProfile?*', 'systemProfiler');
interceptURL(
'GET',
'/api/v1/tables/*/tableProfilerConfig',
'tableProfilerConfig'
);
visitEntityDetailsPage({
term: DATABASE_SERVICE.entity.name,
serviceName: DATABASE_SERVICE.service.name,
entity: EntityType.Table,
});
cy.get('[data-testid="profiler"]').should('be.visible').click();
cy.get('[data-testid="profiler-tab-left-panel"]')
.contains('Table Profile')
.click();
verifyResponseStatusCode('@tableProfiler', 200);
verifyResponseStatusCode('@systemProfiler', 200);
cy.get('[data-testid="profiler-setting-btn"]').click();
cy.get('.ant-modal-body').should('be.visible');
cy.get('[data-testid="slider-input"]')
.clear()
.type(profilerSetting.profileSample);
cy.get('[data-testid="sample-data-count-input"]')
.clear()
.type(profilerSetting.sampleDataCount);
cy.get('[data-testid="exclude-column-select"]')
.scrollIntoView()
.type(`${profilerSetting.excludeColumns}{enter}`);
cy.clickOutside();
cy.get('.CodeMirror-scroll')
.scrollIntoView()
.click()
.type(profilerSetting.profileQuery);
cy.get('[data-testid="include-column-select"]').scrollIntoView().click();
cy.get('.ant-select-dropdown')
.not('.ant-select-dropdown-hidden')
.find(`[title="${profilerSetting.includeColumns}"]`)
.click();
cy.get('[data-testid="enable-partition-switch"]')
.scrollIntoView()
.click();
cy.get('[data-testid="interval-type"]').scrollIntoView().click();
cy.get('.ant-select-dropdown')
.not('.ant-select-dropdown-hidden')
.find(`[title="${profilerSetting.partitionIntervalType}"]`)
.click();
cy.get('#includeColumnsProfiler_partitionColumnName').click();
cy.get('.ant-select-dropdown')
.not('.ant-select-dropdown-hidden')
.find(`[title="${profilerSetting.partitionColumnName}"]`)
.click();
cy.get('[data-testid="partition-value"]')
.scrollIntoView()
.type(profilerSetting.partitionValues);
interceptURL(
'PUT',
'/api/v1/tables/*/tableProfilerConfig',
'updateTableProfilerConfig'
);
cy.get('.ant-modal-footer').contains('Save').scrollIntoView().click();
cy.wait('@updateTableProfilerConfig').then(({ request }) => {
expect(request.body).to.deep.equal({
excludeColumns: ['user_id'],
profileQuery: 'select * from table',
profileSample: 60,
profileSampleType: 'PERCENTAGE',
includeColumns: [{ columnName: 'shop_id' }],
partitioning: {
partitionColumnName: 'name',
partitionIntervalType: 'COLUMN-VALUE',
partitionValues: ['test'],
enablePartitioning: true,
},
sampleDataCount: 100,
});
});
cy.get('[data-testid="table_queries"]').click();
cy.get('[data-testid="profiler"]').click();
// verify profiler setting details
cy.get('[data-testid="profiler-setting-btn"]').click();
// need extra time to load API response
verifyResponseStatusCode('@tableProfilerConfig', 200, { timeout: 10000 });
cy.get('[data-testid="slider-input"]').should(
'have.value',
`${profilerSetting.profileSample}%`
);
cy.get('.CodeMirror-scroll').should(
'contain',
profilerSetting.profileQuery
);
cy.get('[data-testid="exclude-column-select"]').should(
'contain',
profilerSetting.excludeColumns
);
cy.get('[data-testid="enable-partition-switch"]').should(
'have.value',
'true'
);
cy.get('[data-testid="interval-type"]').should(
'contain',
profilerSetting.partitionIntervalType
);
cy.get('[data-testid="column-name"]').should(
'contain',
profilerSetting.partitionColumnName
);
cy.get('[data-testid="partition-value"]').should(
'have.value',
profilerSetting.partitionValues
);
});
}
);