diff --git a/openmetadata-ui/src/main/resources/ui/cypress/constants/constants.js b/openmetadata-ui/src/main/resources/ui/cypress/constants/constants.js index 4ae208f1cf9..0c1eb978259 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/constants/constants.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/constants/constants.js @@ -33,6 +33,13 @@ export const SEARCH_INDEX = { mlmodels: 'mlmodel_search_index', }; +export const DATA_QUALITY_SAMPLE_DATA_TABLE = { + term: 'dim_address', + entity: MYDATA_SUMMARY_OPTIONS.tables, + serviceName: 'sample_data', + testCaseName: 'column_value_max_to_be_between', +}; + export const SEARCH_ENTITY_TABLE = { table_1: { term: 'raw_customer', diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/DataQualityAndProfiler.js b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/DataQualityAndProfiler.js index 15b972608e7..9db7b28289c 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/DataQualityAndProfiler.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/DataQualityAndProfiler.js @@ -14,7 +14,7 @@ /// import { deleteCreatedService, descriptionBox, goToAddNewServicePage, handleIngestionRetry, interceptURL, login, mySqlConnectionInput, scheduleIngestion, testServiceCreationAndIngestion, uuid, verifyResponseStatusCode, visitEntityDetailsPage } from '../../common/common'; -import { DELETE_TERM, LOGIN, MYDATA_SUMMARY_OPTIONS, NEW_COLUMN_TEST_CASE, NEW_TABLE_TEST_CASE, NEW_TEST_SUITE, SERVICE_TYPE, TEAM_ENTITY } from '../../constants/constants'; +import { DATA_QUALITY_SAMPLE_DATA_TABLE, DELETE_TERM, LOGIN, MYDATA_SUMMARY_OPTIONS, NEW_COLUMN_TEST_CASE, NEW_TABLE_TEST_CASE, NEW_TEST_SUITE, SERVICE_TYPE, TEAM_ENTITY } from '../../constants/constants'; const serviceType = 'Mysql'; const serviceName = `${serviceType}-ct-test-${uuid()}`; @@ -392,4 +392,43 @@ describe('Data Quality and Profiler should work properly', () => { cy.goToHomePage(); deleteCreatedService(SERVICE_TYPE.Database, serviceName); }); + + it('Profiler matrix and test case graph should visible', () => { + login(LOGIN.username, LOGIN.password); + cy.goToHomePage(); + const { term, entity, serviceName, testCaseName } = + DATA_QUALITY_SAMPLE_DATA_TABLE; + visitEntityDetailsPage(term, serviceName, entity); + cy.get('[data-testid="inactive-link"]').should('be.visible').contains(term); + cy.get('[data-testid="Profiler & Data Quality"]') + .should('be.visible') + .click(); + cy.get('[data-testid="Profiler & Data Quality"]').should( + 'have.class', + 'active' + ); + interceptURL('GET', '/api/v1/tables/*/columnProfile?*', 'getProfilerInfo'); + + cy.get('[data-row-key="shop_id"] > :nth-child(1) > a') + .scrollIntoView() + .should('be.visible') + .click(); + verifyResponseStatusCode('@getProfilerInfo', 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/testCase?*', 'getTestCaseInfo'); + interceptURL('GET', '/api/v1/testCase/*/testCaseResult?*', 'getTestResult'); + cy.get('[data-testid="profiler-switch"]') + .contains('Data Quality') + .scrollIntoView() + .click(); + verifyResponseStatusCode('@getTestCaseInfo', 200); + cy.get(`[data-testid="${testCaseName}"]`).should('be.visible').click(); + verifyResponseStatusCode('@getTestResult', 200); + cy.get(`[id="${testCaseName}_graph"]`).should('be.visible'); + }); }); diff --git a/openmetadata-ui/src/main/resources/ui/src/components/PipelineStatusList/PipelineStatusList.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/PipelineStatusList/PipelineStatusList.component.tsx index c8b2872ac70..110c4be8783 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/PipelineStatusList/PipelineStatusList.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/PipelineStatusList/PipelineStatusList.component.tsx @@ -29,8 +29,8 @@ import { Pipeline, PipelineStatus } from '../../generated/entity/data/pipeline'; import jsonData from '../../jsons/en'; import { STATUS_OPTIONS } from '../../utils/PipelineDetailsUtils'; import { - getDateToMilliSecondsOfCurrentDate, - getPastDatesToMilliSecondsFromCurrentDate, + getCurrentDateTimeStamp, + getPastDatesTimeStampFromCurrentDate, } from '../../utils/TimeUtils'; import { showErrorToast } from '../../utils/ToastUtils'; import { reactSingleSelectCustomStyle } from '../common/react-select-component/reactSelectCustomStyle'; @@ -78,11 +78,11 @@ const PipelineStatusList: FC = ({ const fetchPipelineStatus = async () => { try { - const startTs = getPastDatesToMilliSecondsFromCurrentDate( + const startTs = getPastDatesTimeStampFromCurrentDate( PROFILER_FILTER_RANGE.last60days.days ); - const endTs = getDateToMilliSecondsOfCurrentDate(); + const endTs = getCurrentDateTimeStamp(); const response = await getPipelineStatus(pipelineFQN, { startTs, diff --git a/openmetadata-ui/src/main/resources/ui/src/components/ProfilerDashboard/component/ProfilerDetailsCard.tsx b/openmetadata-ui/src/main/resources/ui/src/components/ProfilerDashboard/component/ProfilerDetailsCard.tsx index 0e41ce52195..7d8531e7a7f 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/ProfilerDashboard/component/ProfilerDetailsCard.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/ProfilerDashboard/component/ProfilerDetailsCard.tsx @@ -30,6 +30,7 @@ import { ProfilerDetailsCardProps } from '../profilerDashboard.interface'; const ProfilerDetailsCard: React.FC = ({ chartCollection, tickFormatter, + name, }) => { const { data, information } = chartCollection; @@ -58,7 +59,7 @@ const ProfilerDetailsCard: React.FC = ({ {data.length > 0 ? ( - + = ({ /> - + - + - + ); diff --git a/openmetadata-ui/src/main/resources/ui/src/components/ProfilerDashboard/component/TestSummary.tsx b/openmetadata-ui/src/main/resources/ui/src/components/ProfilerDashboard/component/TestSummary.tsx index bfac668582a..4043141274c 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/ProfilerDashboard/component/TestSummary.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/ProfilerDashboard/component/TestSummary.tsx @@ -40,9 +40,9 @@ import { } from '../../../generated/tests/testCase'; import { getEncodedFqn } from '../../../utils/StringsUtils'; import { - getDateToMilliSecondsOfCurrentDate, + getCurrentDateTimeStamp, getFormattedDateFromSeconds, - getPastDatesToMilliSecondsFromCurrentDate, + getPastDatesTimeStampFromCurrentDate, } from '../../../utils/TimeUtils'; import { showErrorToast } from '../../../utils/ToastUtils'; import ErrorPlaceHolder from '../../common/error-with-placeholder/ErrorPlaceHolder'; @@ -130,11 +130,11 @@ const TestSummary: React.FC = ({ data }) => { if (isEmpty(data)) return; try { - const startTs = getPastDatesToMilliSecondsFromCurrentDate( + const startTs = getPastDatesTimeStampFromCurrentDate( PROFILER_FILTER_RANGE[selectedTimeRange].days ); - const endTs = getDateToMilliSecondsOfCurrentDate(); + const endTs = getCurrentDateTimeStamp(); const { data: chartData } = await getListTestCaseResults( getEncodedFqn(data.fullyQualifiedName || ''), @@ -217,7 +217,10 @@ const TestSummary: React.FC = ({ data }) => { {results.length ? ( - + { const fetchProfilerData = async (fqn: string, days = 3) => { try { - const startTs = getPastDatesToMilliSecondsFromCurrentDate(days); + const startTs = getPastDatesTimeStampFromCurrentDate(days); - const endTs = getDateToMilliSecondsOfCurrentDate(); + const endTs = getCurrentDateTimeStamp(); const { data } = await getColumnProfilerList(fqn, { startTs, diff --git a/openmetadata-ui/src/main/resources/ui/src/utils/TimeUtils.ts b/openmetadata-ui/src/main/resources/ui/src/utils/TimeUtils.ts index a1a2ef367a2..7b403fc55ff 100644 --- a/openmetadata-ui/src/main/resources/ui/src/utils/TimeUtils.ts +++ b/openmetadata-ui/src/main/resources/ui/src/utils/TimeUtils.ts @@ -275,15 +275,13 @@ export const getDateOrTimeFromSeconds = (seconds: number, format?: string) => * the current date * @param {number} pastDayCount - The number of days you want to go back from the current date. */ -export const getPastDatesToMilliSecondsFromCurrentDate = ( - pastDayCount: number -) => DateTime.now().minus({ days: pastDayCount }).toMillis(); +export const getPastDatesTimeStampFromCurrentDate = (pastDayCount: number) => + DateTime.now().minus({ days: pastDayCount }).toUnixInteger(); /** * Get the current date and time in seconds. */ -export const getDateToMilliSecondsOfCurrentDate = () => - DateTime.now().toMillis(); +export const getCurrentDateTimeStamp = () => DateTime.now().toUnixInteger(); /** * It takes a timestamp in seconds and returns a formatted date string