From 151dd3e48bd62a6d3ac80db9fa37593b9c4f4e76 Mon Sep 17 00:00:00 2001 From: Shailesh Parmar Date: Tue, 23 Jul 2024 17:57:02 +0530 Subject: [PATCH] Minor: fixed edit modal issue for sql test case (#17132) * Minor: fixed edit modal issue for sql test case * fixed test --- .../e2e/Pages/DataQualityAndProfiler.spec.ts | 77 ------ .../ui/playwright/e2e/Pages/TestCases.spec.ts | 251 ++++++++++++------ .../ui/playwright/utils/testCases.ts | 24 ++ .../AddDataQualityTest/EditTestCaseModal.tsx | 22 +- 4 files changed, 209 insertions(+), 165 deletions(-) create mode 100644 openmetadata-ui/src/main/resources/ui/playwright/utils/testCases.ts diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/DataQualityAndProfiler.spec.ts b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/DataQualityAndProfiler.spec.ts index b2643e7d1f8..7ebfbe6b767 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/DataQualityAndProfiler.spec.ts +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/DataQualityAndProfiler.spec.ts @@ -738,83 +738,6 @@ describe( }); }); - it('SQL query should be visible while editing the test case', () => { - const { - term, - entity, - serviceName, - sqlTestCase, - sqlQuery, - sqlTestCaseName, - } = DATA_QUALITY_SAMPLE_DATA_TABLE; - interceptURL( - 'GET', - `api/v1/tables/name/${serviceName}.*.${term}?fields=*&include=all`, - 'waitForPageLoad' - ); - visitEntityDetailsPage({ term, serviceName, entity }); - verifyResponseStatusCode('@waitForPageLoad', 200); - cy.get('[data-testid="entity-header-display-name"]').should( - 'contain', - term - ); - - cy.get('[data-testid="profiler"]').click(); - 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_testName').type(sqlTestCaseName); - cy.get('#tableTestForm_testTypeId').scrollIntoView().click(); - cy.contains(sqlTestCase).should('be.visible').click(); - cy.get('.CodeMirror-scroll') - .scrollIntoView() - .should('be.visible') - .type(sqlQuery); - cy.get(descriptionBox).scrollIntoView().type(sqlTestCase); - - cy.get('[data-testid="submit-test"]') - .scrollIntoView() - .should('be.visible') - .click(); - - interceptURL('GET', '/api/v1/dataQuality/testCases?fields=*', 'testCase'); - interceptURL( - 'GET', - '/api/v1/dataQuality/testDefinitions/*', - 'testCaseDefinition' - ); - - cy.get('[data-testid="success-line"]') - .scrollIntoView() - .should('be.visible'); - cy.get('[data-testid="view-service-button"]') - .should('be.visible') - .click(); - cy.get('[data-testid="profiler-tab-left-panel"]') - .contains('Data Quality') - .click(); - verifyResponseStatusCode('@testCase', 200); - cy.get('[data-testid="my_sql_test_case_cypress"]') - .scrollIntoView() - .should('be.visible'); - cy.get('[data-testid="edit-my_sql_test_case_cypress"]') - .should('be.visible') - .click(); - - verifyResponseStatusCode('@testCaseDefinition', 200); - cy.get('#tableTestForm').should('be.visible'); - cy.get('.CodeMirror-scroll') - .scrollIntoView() - .should('be.visible') - .contains(sqlQuery); - }); - it('Array params value should be visible while editing the test case', () => { const tableName = DATABASE_SERVICE.entity.name; goToProfilerTab({ diff --git a/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/TestCases.spec.ts b/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/TestCases.spec.ts index d9b86dddb95..0d5c7759fda 100644 --- a/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/TestCases.spec.ts +++ b/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/TestCases.spec.ts @@ -13,11 +13,14 @@ import { expect, test } from '@playwright/test'; import { TableClass } from '../../support/entity/TableClass'; import { getApiContext, redirectToHomePage } from '../../utils/common'; +import { deleteTestCase } from '../../utils/testCases'; // use the admin user to login test.use({ storageState: 'playwright/.auth/admin.json' }); test('Table difference test case', async ({ page }) => { + test.slow(); + await redirectToHomePage(page); const { afterAction, apiContext } = await getApiContext(page); const table1 = new TableClass(); @@ -33,98 +36,184 @@ test('Table difference test case', async ({ page }) => { await table1.visitEntityPage(page); await page.getByText('Profiler & Data Quality').click(); - await test.step('Create', async () => { - await page.getByTestId('profiler-add-table-test-btn').click(); - await page.getByTestId('test-case').click(); - await page.getByTestId('test-case-name').fill(testCase.name); - await page.getByTestId('test-type').click(); - await page.getByTitle('Compare 2 tables for').click(); - const tableSearchResponse = page.waitForResponse( - `/api/v1/search/query?q=*${encodeURIComponent( - testCase.table2 - )}*index=table_search_index*` - ); - await page.click('#tableTestForm_params_table2'); - await page.fill(`#tableTestForm_params_table2`, testCase.table2); - await tableSearchResponse; - await page - .getByTitle(table2.entityResponseData?.['fullyQualifiedName']) - .click(); + try { + await test.step('Create', async () => { + await page.getByTestId('profiler-add-table-test-btn').click(); + await page.getByTestId('test-case').click(); + await page.getByTestId('test-case-name').fill(testCase.name); + await page.getByTestId('test-type').click(); + await page.getByTitle('Compare 2 tables for').click(); + const tableSearchResponse = page.waitForResponse( + `/api/v1/search/query?q=*${encodeURIComponent( + testCase.table2 + )}*index=table_search_index*` + ); + await page.click('#tableTestForm_params_table2'); + await page.fill(`#tableTestForm_params_table2`, testCase.table2); + await tableSearchResponse; + await page + .getByTitle(table2.entityResponseData?.['fullyQualifiedName']) + .click(); - await page.fill(`#tableTestForm_params_keyColumns_0_value`, 'user_id'); - await page.getByTitle('user_id').click(); - await page.fill('#tableTestForm_params_threshold', testCase.threshold); - await page.fill('#tableTestForm_params_useColumns_0_value', 'user_id'); + await page.fill(`#tableTestForm_params_keyColumns_0_value`, 'user_id'); + await page.getByTitle('user_id').click(); + await page.fill('#tableTestForm_params_threshold', testCase.threshold); + await page.fill('#tableTestForm_params_useColumns_0_value', 'user_id'); - await expect(page.getByTitle('user_id').nth(2)).toHaveClass( - /ant-select-item-option-disabled/ - ); + await expect(page.getByTitle('user_id').nth(2)).toHaveClass( + /ant-select-item-option-disabled/ + ); - await page.locator('#tableTestForm_params_useColumns_0_value').clear(); - await page.fill('#tableTestForm_params_useColumns_0_value', 'shop_id'); - await page.getByTitle('shop_id').click(); + await page.locator('#tableTestForm_params_useColumns_0_value').clear(); + await page.fill('#tableTestForm_params_useColumns_0_value', 'shop_id'); + await page.getByTitle('shop_id').click(); - await page.fill('#tableTestForm_params_where', 'test'); - const createTestCaseResponse = page.waitForResponse( - `/api/v1/dataQuality/testCases` - ); - await page.getByTestId('submit-test').click(); - await createTestCaseResponse; - const tableTestResponse = page.waitForResponse( - `/api/v1/dataQuality/testCases?fields=*` - ); - await page.getByTestId('view-service-button').click(); - await tableTestResponse; - }); + await page.fill('#tableTestForm_params_where', 'test'); + const createTestCaseResponse = page.waitForResponse( + `/api/v1/dataQuality/testCases` + ); + await page.getByTestId('submit-test').click(); + await createTestCaseResponse; + const tableTestResponse = page.waitForResponse( + `/api/v1/dataQuality/testCases?fields=*` + ); + await page.getByTestId('view-service-button').click(); + await tableTestResponse; + }); - await test.step('Edit', async () => { - await expect( - page.getByTestId(testCase.name).getByRole('link') - ).toBeVisible(); + await test.step('Edit', async () => { + await expect( + page.getByTestId(testCase.name).getByRole('link') + ).toBeVisible(); - await page.getByTestId(`edit-${testCase.name}`).click(); + await page.getByTestId(`edit-${testCase.name}`).click(); - await expect(page.locator('.ant-modal-title')).toHaveText( - `Edit ${testCase.name}` - ); + await expect(page.locator('.ant-modal-title')).toHaveText( + `Edit ${testCase.name}` + ); - await page - .locator('label') - .filter({ hasText: 'Key Columns' }) - .getByRole('button') - .click(); - await page.fill('#tableTestForm_params_keyColumns_1_value', 'email'); - await page.getByTitle('email', { exact: true }).click(); + await page + .locator('label') + .filter({ hasText: 'Key Columns' }) + .getByRole('button') + .click(); + await page.fill('#tableTestForm_params_keyColumns_1_value', 'email'); + await page.getByTitle('email', { exact: true }).click(); - await page - .locator('label') - .filter({ hasText: 'Use Columns' }) - .getByRole('button') - .click(); - await page.fill('#tableTestForm_params_useColumns_1_value', 'name'); - await page.getByTitle('name', { exact: true }).click(); - await page.getByRole('button', { name: 'Submit' }).click(); + await page + .locator('label') + .filter({ hasText: 'Use Columns' }) + .getByRole('button') + .click(); + await page.fill('#tableTestForm_params_useColumns_1_value', 'name'); + await page.getByTitle('name', { exact: true }).click(); + await page.getByRole('button', { name: 'Submit' }).click(); - await expect(page.getByRole('alert')).toContainText( - 'Test case updated successfully.' - ); + await expect(page.getByRole('alert')).toContainText( + 'Test case updated successfully.' + ); - await page.getByTestId('content-wrapper').getByLabel('close').click(); - }); + await page.getByTestId('content-wrapper').getByLabel('close').click(); + }); - await test.step('Delete', async () => { - await page.getByTestId(`delete-${testCase.name}`).click(); - await page.fill('#deleteTextInput', 'DELETE'); + await test.step('Delete', async () => { + await deleteTestCase(page, testCase.name); + }); + } catch (error) { + await table1.delete(apiContext); + await table2.delete(apiContext); - await expect(page.getByTestId('confirm-button')).toBeEnabled(); - - await page.getByTestId('confirm-button').click(); - - await expect(page.getByRole('alert')).toHaveText(/deleted successfully!/); - }); - - await table1.delete(apiContext); - await table2.delete(apiContext); - - await afterAction(); + await afterAction(); + } +}); + +test('Custom SQL Query', async ({ page }) => { + test.slow(); + + await redirectToHomePage(page); + const { afterAction, apiContext } = await getApiContext(page); + const table = new TableClass(); + await table.create(apiContext); + const testCase = { + name: `${table.entity.name}_test_case`, + displayName: 'SQL Test Case Display Name', + sqlQuery: 'SELECT * FROM table', + }; + + await table.visitEntityPage(page); + await page.getByText('Profiler & Data Quality').click(); + + try { + await test.step('Create', async () => { + await page.getByTestId('profiler-add-table-test-btn').click(); + await page.getByTestId('test-case').click(); + await page.getByTestId('test-case-name').fill(testCase.name); + await page.getByTestId('test-type').click(); + await page.getByTitle('Custom SQL Query').click(); + await page.click('#tableTestForm_params_strategy'); + await page.locator('.CodeMirror-scroll').click(); + await page + .getByTestId('code-mirror-container') + .getByRole('textbox') + .fill(testCase.sqlQuery); + await page.getByLabel('Strategy:').click(); + await page.getByTitle('ROWS').click(); + await page.fill('#tableTestForm_params_threshold', '23'); + const createTestCaseResponse = page.waitForResponse( + `/api/v1/dataQuality/testCases` + ); + await page.getByTestId('submit-test').click(); + await createTestCaseResponse; + const tableTestResponse = page.waitForResponse( + `/api/v1/dataQuality/testCases?fields=*` + ); + await page.getByTestId('view-service-button').click(); + await tableTestResponse; + }); + + await test.step('Edit', async () => { + await expect( + page.getByTestId(testCase.name).getByRole('link') + ).toBeVisible(); + + await page.getByTestId(`edit-${testCase.name}`).click(); + + await expect(page.locator('.ant-modal-title')).toHaveText( + `Edit ${testCase.name}` + ); + await expect(page.locator('#tableTestForm_name')).toHaveValue( + testCase.name + ); + await expect(page.getByTestId('code-mirror-container')).toContainText( + testCase.sqlQuery + ); + + await page.locator('#tableTestForm_displayName').clear(); + await page.fill('#tableTestForm_displayName', testCase.displayName); + + await page.locator('.CodeMirror-scroll').click(); + await page + .getByTestId('code-mirror-container') + .getByRole('textbox') + .fill(' update'); + await page.getByText('ROWS').click(); + await page.getByTitle('COUNT').click(); + await page.getByPlaceholder('Enter a Threshold').clear(); + await page.getByPlaceholder('Enter a Threshold').fill('244'); + await page.getByRole('button', { name: 'Submit' }).click(); + + await expect(page.getByRole('alert')).toContainText( + 'Test case updated successfully.' + ); + + await page.getByTestId('content-wrapper').getByLabel('close').click(); + }); + + await test.step('Delete', async () => { + await deleteTestCase(page, testCase.name); + }); + } catch (error) { + await table.delete(apiContext); + await afterAction(); + } }); diff --git a/openmetadata-ui/src/main/resources/ui/playwright/utils/testCases.ts b/openmetadata-ui/src/main/resources/ui/playwright/utils/testCases.ts new file mode 100644 index 00000000000..af1e136e24a --- /dev/null +++ b/openmetadata-ui/src/main/resources/ui/playwright/utils/testCases.ts @@ -0,0 +1,24 @@ +/* + * Copyright 2024 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 { expect, Page } from '@playwright/test'; + +export const deleteTestCase = async (page: Page, testCaseName: string) => { + await page.getByTestId(`delete-${testCaseName}`).click(); + await page.fill('#deleteTextInput', 'DELETE'); + + await expect(page.getByTestId('confirm-button')).toBeEnabled(); + + await page.getByTestId('confirm-button').click(); + + await expect(page.getByRole('alert')).toHaveText(/deleted successfully!/); +}; diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/AddDataQualityTest/EditTestCaseModal.tsx b/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/AddDataQualityTest/EditTestCaseModal.tsx index d372f98425e..6548d6150a6 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/AddDataQualityTest/EditTestCaseModal.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/AddDataQualityTest/EditTestCaseModal.tsx @@ -15,7 +15,7 @@ import { Form, FormProps, Input } from 'antd'; import Modal from 'antd/lib/modal/Modal'; import { AxiosError } from 'axios'; import { compare } from 'fast-json-patch'; -import { isEmpty, isEqual, pick } from 'lodash'; +import { isArray, isEmpty, isEqual, pick } from 'lodash'; import React, { useEffect, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { ENTITY_NAME_REGEX } from '../../../constants/regex.constants'; @@ -144,14 +144,22 @@ const EditTestCaseModal: React.FC = ({ (definition) => definition.name === curr.name ); - return { - ...acc, - [curr.name || '']: - param?.dataType === TestDataType.Array - ? (JSON.parse(curr.value || '[]') as string[]).map((val) => ({ + if (param?.dataType === TestDataType.Array) { + const value = JSON.parse(curr.value || '[]'); + + return { + ...acc, + [curr.name || '']: isArray(value) + ? value.map((val) => ({ value: val, })) - : curr.value, + : value, + }; + } + + return { + ...acc, + [curr.name || '']: curr.value, }; }, {}); };