From 9286933d5c3456f1d75510c4488ee7c0daed6814 Mon Sep 17 00:00:00 2001 From: Ashish Gupta Date: Fri, 10 Oct 2025 18:57:04 +0530 Subject: [PATCH] chore(ui): refactor data contract spec test (#23741) * chore(ui): fix data contract flaky test around contract tab not found * modify the test to have their own table to run to avoid flakiness * fix contract failing * revert unwanted commit * change the contract test admin page way * fix the blank page issue after redirect --- .../e2e/Pages/DataContracts.spec.ts | 674 ++++++++++-------- .../ui/playwright/utils/advancedSearch.ts | 8 + 2 files changed, 388 insertions(+), 294 deletions(-) diff --git a/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/DataContracts.spec.ts b/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/DataContracts.spec.ts index fc41bb00cdd..521ea135ab6 100644 --- a/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/DataContracts.spec.ts +++ b/openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/DataContracts.spec.ts @@ -36,6 +36,7 @@ import { selectOption } from '../../utils/advancedSearch'; import { resetTokenFromBotPage } from '../../utils/bot'; import { clickOutside, + getApiContext, redirectToHomePage, toastNotification, } from '../../utils/common'; @@ -54,10 +55,10 @@ import { assignTier, } from '../../utils/entity'; import { settingClick } from '../../utils/sidebar'; +import { test } from '../fixtures/pages'; const adminUser = new UserClass(); - -const test = base.extend<{ page: Page }>({ +const testPersona = base.extend<{ page: Page }>({ page: async ({ browser }, use) => { const adminPage = await browser.newPage(); await adminUser.login(adminPage); @@ -67,57 +68,8 @@ const test = base.extend<{ page: Page }>({ }); test.describe('Data Contracts', () => { - const table = new TableClass(); - const table2 = new TableClass(); - const testClassification = new ClassificationClass(); - const testTag = new TagClass({ - classification: testClassification.data.name, - }); - const testGlossary = new Glossary(); - const testGlossaryTerm = new GlossaryTerm(testGlossary); - const testPersona = new PersonaClass(); - test.beforeAll('Setup pre-requests', async ({ browser }) => { - test.slow(true); - - const { apiContext, afterAction, page } = await performAdminLogin(browser); - await table.create(apiContext); - await table2.create(apiContext); - await testClassification.create(apiContext); - await testTag.create(apiContext); - await testGlossary.create(apiContext); - await testGlossaryTerm.create(apiContext); - await testPersona.create(apiContext); - await adminUser.create(apiContext); - await adminUser.setAdminRole(apiContext); - await adminUser.patch({ - apiContext, - patchData: [ - { - op: 'add', - path: '/personas/0', - value: { - id: testPersona.responseData.id, - name: testPersona.responseData.name, - displayName: testPersona.responseData.displayName, - fullyQualifiedName: testPersona.responseData.fullyQualifiedName, - type: 'persona', - }, - }, - { - op: 'add', - path: '/defaultPersona', - value: { - id: testPersona.responseData.id, - name: testPersona.responseData.name, - displayName: testPersona.responseData.displayName, - fullyQualifiedName: testPersona.responseData.fullyQualifiedName, - type: 'persona', - }, - }, - ], - }); - + const { afterAction, page } = await performAdminLogin(browser); if (!process.env.PLAYWRIGHT_IS_OSS) { // Todo: Remove this patch once the issue is fixed #19140 await resetTokenFromBotPage(page, 'testsuite-bot'); @@ -126,9 +78,28 @@ test.describe('Data Contracts', () => { await afterAction(); }); + test.beforeEach('Redirect to Home Page', async ({ page }) => { + await redirectToHomePage(page); + }); + test('Create Data Contract and validate', async ({ page }) => { test.setTimeout(360000); + const table = new TableClass(); + const testClassification = new ClassificationClass(); + const testTag = new TagClass({ + classification: testClassification.data.name, + }); + const testGlossary = new Glossary(); + const testGlossaryTerm = new GlossaryTerm(testGlossary); + + const { apiContext } = await getApiContext(page); + await table.create(apiContext); + await testClassification.create(apiContext); + await testTag.create(apiContext); + await testGlossary.create(apiContext); + await testGlossaryTerm.create(apiContext); + await test.step('Redirect to Home Page and visit entity', async () => { await redirectToHomePage(page); await table.visitEntityPage(page); @@ -421,11 +392,18 @@ test.describe('Data Contracts', () => { 'Pipeline will only be triggered manually.' ); + const pipelineResponse = page.waitForResponse( + '/api/v1/services/ingestionPipelines' + ); + const testCaseResponse = page.waitForResponse( '/api/v1/dataQuality/testCases' ); await page.click('[data-testid="create-btn"]'); await testCaseResponse; + await pipelineResponse; + + await expect(page.getByRole('dialog')).not.toBeVisible(); await page.waitForLoadState('networkidle'); await page.waitForSelector('[data-testid="loader"]', { @@ -681,246 +659,6 @@ test.describe('Data Contracts', () => { }); }); - test('Contract Status badge should be visible on condition if Contract Tab is present/hidden by Persona', async ({ - page, - }) => { - test.slow(true); - - await test.step( - 'Create Data Contract in Table and validate it fails', - async () => { - await table2.visitEntityPage(page); - - // Open contract section and start adding contract - await page.click('[data-testid="contract"]'); - await page.waitForSelector('[data-testid="loader"]', { - state: 'detached', - }); - - await expect(page.getByTestId('no-data-placeholder')).toBeVisible(); - await expect(page.getByTestId('add-contract-button')).toBeVisible(); - - await page.getByTestId('add-contract-button').click(); - - await expect(page.getByTestId('add-contract-card')).toBeVisible(); - - // Fill Contract Details form - await page - .getByTestId('contract-name') - .fill(DATA_CONTRACT_DETAILS.name); - await page.fill( - '.om-block-editor[contenteditable="true"]', - DATA_CONTRACT_DETAILS.description - ); - - await page.getByTestId('select-owners').click(); - await page.locator('.rc-virtual-list-holder-inner li').first().click(); - - await expect(page.getByTestId('user-tag')).toBeVisible(); - - // Fill Contract Schema form - await page - .getByTestId('add-contract-card') - .getByRole('tab', { name: 'Schema' }) - .click(); - - await page - .locator('input[type="checkbox"][aria-label="Select all"]') - .check(); - - await expect( - page.getByRole('checkbox', { name: 'Select all' }) - ).toBeChecked(); - - // Fill Contract Semantics form - await page.getByRole('tab', { name: 'Semantics' }).click(); - - await expect(page.getByTestId('add-semantic-button')).toBeDisabled(); - - await page.fill('#semantics_0_name', DATA_CONTRACT_SEMANTICS1.name); - await page.fill( - '#semantics_0_description', - DATA_CONTRACT_SEMANTICS1.description - ); - - const ruleLocator = page.locator('.group').nth(0); - await selectOption( - page, - ruleLocator.locator('.group--field .ant-select'), - DATA_CONTRACT_SEMANTICS1.rules[0].field, - true - ); - await selectOption( - page, - ruleLocator.locator('.rule--operator .ant-select'), - DATA_CONTRACT_SEMANTICS1.rules[0].operator - ); - await selectOption( - page, - ruleLocator.locator('.rule--value .ant-select'), - 'admin', - true - ); - await page.getByTestId('save-semantic-button').click(); - - await expect( - page - .getByTestId('contract-semantics-card-0') - .locator('.semantic-form-item-title') - ).toContainText(DATA_CONTRACT_SEMANTICS1.name); - - // Save contract and validate for semantics - should fail initially - await saveAndTriggerDataContractValidation(page, true); - - await expect( - page.getByTestId('contract-status-card-item-semantics-status') - ).toContainText('Failed'); - await expect( - page.getByTestId('data-contract-latest-result-btn') - ).toContainText('Contract Failed'); - } - ); - - await test.step('Create Persona and assign user to it', async () => { - await redirectToHomePage(page); - - const personaGetResponse = page.waitForResponse('/api/v1/personas**'); - await settingClick(page, GlobalSettingOptions.PERSONA); - await personaGetResponse; - - await page.waitForSelector('.ant-skeleton-content', { - state: 'detached', - }); - - // Navigate to persona details - await page - .getByTestId(`persona-details-card-${testPersona.data.name}`) - .click(); - await page.getByRole('tab', { name: 'Users' }).click(); - - // Add user to persona - await page.getByTestId('add-persona-button').click(); - await page.waitForSelector('[data-testid="loader"]', { - state: 'detached', - }); - - const searchUser = page.waitForResponse( - `/api/v1/search/query?q=*${encodeURIComponent( - adminUser.responseData.displayName - )}*` - ); - await page - .getByTestId('searchbar') - .fill(adminUser.responseData.displayName); - await searchUser; - - await page - .getByRole('listitem', { name: adminUser.responseData.displayName }) - .click(); - - const personaResponse = page.waitForResponse('/api/v1/personas/*'); - - await page.getByTestId('selectable-list-update-btn').click(); - await personaResponse; - }); - - await test.step( - 'Verify Contract tab and status badge are visible if persona is set', - async () => { - await redirectToHomePage(page); - await table2.visitEntityPage(page); - await page.waitForLoadState('networkidle'); - await page.waitForSelector('[data-testid="loader"]', { - state: 'detached', - }); - - // Verify Contract tab is not visible (should be hidden by persona customization) - await expect(page.getByTestId('contract')).toBeVisible(); - - // Verify Contract status badge is not visible in header - await expect( - page.getByTestId('data-contract-latest-result-btn') - ).toBeVisible(); - - // Additional verification: Check that other tabs are still visible - await expect(page.getByTestId('schema')).toBeVisible(); - await expect(page.getByTestId('activity_feed')).toBeVisible(); - await expect(page.getByTestId('sample_data')).toBeVisible(); - await expect(page.getByTestId('table_queries')).toBeVisible(); - await expect(page.getByTestId('profiler')).toBeVisible(); - await expect(page.getByTestId('lineage')).toBeVisible(); - await expect(page.getByTestId('custom_properties')).toBeVisible(); - } - ); - - await test.step('Customize Table page to hide Contract tab', async () => { - await settingClick(page, GlobalSettingOptions.PERSONA); - await page.waitForLoadState('networkidle'); - await page.waitForSelector('[data-testid="loader"]', { - state: 'detached', - }); - - // Navigate to persona details and customize UI - await page - .getByTestId(`persona-details-card-${testPersona.data.name}`) - .click(); - await page.getByRole('tab', { name: 'Customize UI' }).click(); - await page.waitForLoadState('networkidle'); - - // Navigate to Table customization - await page.getByTestId('data-assets').getByText('Data Assets').click(); - await page.getByText('Table', { exact: true }).click(); - - await page.waitForSelector('[data-testid="loader"]', { - state: 'detached', - }); - - // Hide the Contract tab - await page.getByTestId('tab-contract').click(); - await page.getByText('Hide', { exact: true }).click(); - - // Save the customization - await page.getByTestId('save-button').click(); - await toastNotification( - page, - /^Page layout (created|updated) successfully\.$/ - ); - }); - - await test.step( - 'Verify Contract tab and status badge are hidden after persona customization', - async () => { - // After applying persona customization to hide the contract tab, - // we need to verify that the contract tab and status badge are not visible - // when viewing the table page with the customized persona. - - await redirectToHomePage(page); - await table2.visitEntityPage(page); - await page.waitForLoadState('networkidle'); - await page.waitForSelector('[data-testid="loader"]', { - state: 'detached', - }); - - // Verify Contract tab is not visible (should be hidden by persona customization) - await expect(page.getByTestId('contract')).not.toBeVisible(); - - // Verify Contract status badge is not visible in header - await expect( - page.getByTestId('data-contract-latest-result-btn') - ).not.toBeVisible(); - - // Additional verification: Check that other tabs are still visible - await expect(page.getByTestId('schema')).toBeVisible(); - await expect(page.getByTestId('activity_feed')).toBeVisible(); - await expect(page.getByTestId('sample_data')).toBeVisible(); - await expect(page.getByTestId('table_queries')).toBeVisible(); - await expect(page.getByTestId('profiler')).toBeVisible(); - await expect(page.getByTestId('lineage')).toBeVisible(); - await expect(page.getByTestId('custom_properties')).toBeVisible(); - } - ); - }); - test('Pagination in Schema Tab with Selection Persistent', async ({ page, }) => { @@ -1232,6 +970,21 @@ test.describe('Data Contracts', () => { }) => { test.slow(true); + const table = new TableClass(); + const testClassification = new ClassificationClass(); + const testTag = new TagClass({ + classification: testClassification.data.name, + }); + const testGlossary = new Glossary(); + const testGlossaryTerm = new GlossaryTerm(testGlossary); + + const { apiContext } = await getApiContext(page); + await table.create(apiContext); + await testClassification.create(apiContext); + await testTag.create(apiContext); + await testGlossary.create(apiContext); + await testGlossaryTerm.create(apiContext); + await redirectToHomePage(page); await table.visitEntityPage(page); await page.click('[data-testid="contract"]'); @@ -1402,6 +1155,21 @@ test.describe('Data Contracts', () => { test('Semantic with Not_Contains Operator should work for Tier, Tag and Glossary', async ({ page, }) => { + const table = new TableClass(); + const testClassification = new ClassificationClass(); + const testTag = new TagClass({ + classification: testClassification.data.name, + }); + const testGlossary = new Glossary(); + const testGlossaryTerm = new GlossaryTerm(testGlossary); + + const { apiContext } = await getApiContext(page); + await table.create(apiContext); + await testClassification.create(apiContext); + await testTag.create(apiContext); + await testGlossary.create(apiContext); + await testGlossaryTerm.create(apiContext); + await redirectToHomePage(page); await table.visitEntityPage(page); await page.click('[data-testid="contract"]'); @@ -1574,6 +1342,10 @@ test.describe('Data Contracts', () => { }); test('Nested Column should not be selectable', async ({ page }) => { + const { apiContext } = await getApiContext(page); + const table = new TableClass(); + await table.create(apiContext); + const entityFQN = table.entityResponseData.fullyQualifiedName; await redirectToHomePage(page); await table.visitEntityPage(page); @@ -1642,6 +1414,10 @@ test.describe('Data Contracts', () => { test('should allow adding a semantic with multiple rules', async ({ page, }) => { + const { apiContext } = await getApiContext(page); + const table = new TableClass(); + await table.create(apiContext); + await redirectToHomePage(page); await table.visitEntityPage(page); await page.click('[data-testid="contract"]'); @@ -1717,6 +1493,10 @@ test.describe('Data Contracts', () => { test('should allow adding a second semantic and verify its rule', async ({ page, }) => { + const { apiContext } = await getApiContext(page); + const table = new TableClass(); + await table.create(apiContext); + await redirectToHomePage(page); await table.visitEntityPage(page); await page.click('[data-testid="contract"]'); @@ -1806,6 +1586,10 @@ test.describe('Data Contracts', () => { test('should allow editing a semantic and reflect changes', async ({ page, }) => { + const { apiContext } = await getApiContext(page); + const table = new TableClass(); + await table.create(apiContext); + await redirectToHomePage(page); await table.visitEntityPage(page); await page.click('[data-testid="contract"]'); @@ -1860,6 +1644,10 @@ test.describe('Data Contracts', () => { test('should allow deleting a semantic and remove it from the list', async ({ page, }) => { + const { apiContext } = await getApiContext(page); + const table = new TableClass(); + await table.create(apiContext); + await redirectToHomePage(page); await table.visitEntityPage(page); await page.click('[data-testid="contract"]'); @@ -1925,10 +1713,14 @@ test.describe('Data Contracts', () => { }); test('Add and update Security and SLA tabs', async ({ page }) => { - await redirectToHomePage(page); - await table.visitEntityPage(page); + const { apiContext } = await getApiContext(page); + const table = new TableClass(); + await table.create(apiContext); await test.step('Add Security and SLA Details', async () => { + await redirectToHomePage(page); + await table.visitEntityPage(page); + await page.click('[data-testid="contract"]'); await page.waitForSelector('[data-testid="loader"]', { state: 'detached', @@ -2148,3 +1940,297 @@ test.describe('Data Contracts', () => { }); }); }); + +testPersona.describe('Data Contracts With Persona', () => { + test.beforeAll('Setup pre-requests', async ({ browser }) => { + const { apiContext, afterAction } = await performAdminLogin(browser); + await adminUser.create(apiContext); + await adminUser.setAdminRole(apiContext); + await afterAction(); + }); + + testPersona( + 'Contract Status badge should be visible on condition if Contract Tab is present/hidden by Persona', + async ({ page }) => { + testPersona.slow(true); + const { apiContext } = await getApiContext(page); + const table = new TableClass(); + const persona = new PersonaClass(); + await table.create(apiContext); + await persona.create(apiContext); + await adminUser.patch({ + apiContext, + patchData: [ + { + op: 'add', + path: '/personas/0', + value: { + id: persona.responseData.id, + name: persona.responseData.name, + displayName: persona.responseData.displayName, + fullyQualifiedName: persona.responseData.fullyQualifiedName, + type: 'persona', + }, + }, + { + op: 'add', + path: '/defaultPersona', + value: { + id: persona.responseData.id, + name: persona.responseData.name, + displayName: persona.responseData.displayName, + fullyQualifiedName: persona.responseData.fullyQualifiedName, + type: 'persona', + }, + }, + ], + }); + + await testPersona.step( + 'Create Data Contract in Table and validate it fails', + async () => { + await table.visitEntityPage(page); + + // Open contract section and start adding contract + await page.click('[data-testid="contract"]'); + await page.waitForSelector('[data-testid="loader"]', { + state: 'detached', + }); + + await expect(page.getByTestId('no-data-placeholder')).toBeVisible(); + await expect(page.getByTestId('add-contract-button')).toBeVisible(); + + await page.getByTestId('add-contract-button').click(); + + await expect(page.getByTestId('add-contract-card')).toBeVisible(); + + // Fill Contract Details form + await page + .getByTestId('contract-name') + .fill(DATA_CONTRACT_DETAILS.name); + await page.fill( + '.om-block-editor[contenteditable="true"]', + DATA_CONTRACT_DETAILS.description + ); + + await page.getByTestId('select-owners').click(); + await page + .locator('.rc-virtual-list-holder-inner li') + .first() + .click(); + + await expect(page.getByTestId('user-tag')).toBeVisible(); + + // Fill Contract Schema form + await page + .getByTestId('add-contract-card') + .getByRole('tab', { name: 'Schema' }) + .click(); + + await page + .locator('input[type="checkbox"][aria-label="Select all"]') + .check(); + + await expect( + page.getByRole('checkbox', { name: 'Select all' }) + ).toBeChecked(); + + // Fill Contract Semantics form + await page.getByRole('tab', { name: 'Semantics' }).click(); + + await expect(page.getByTestId('add-semantic-button')).toBeDisabled(); + + await page.fill('#semantics_0_name', DATA_CONTRACT_SEMANTICS1.name); + await page.fill( + '#semantics_0_description', + DATA_CONTRACT_SEMANTICS1.description + ); + + const ruleLocator = page.locator('.group').nth(0); + await selectOption( + page, + ruleLocator.locator('.group--field .ant-select'), + DATA_CONTRACT_SEMANTICS1.rules[0].field, + true + ); + await selectOption( + page, + ruleLocator.locator('.rule--operator .ant-select'), + DATA_CONTRACT_SEMANTICS1.rules[0].operator + ); + await selectOption( + page, + ruleLocator.locator('.rule--value .ant-select'), + 'admin', + true + ); + await page.getByTestId('save-semantic-button').click(); + + await expect( + page + .getByTestId('contract-semantics-card-0') + .locator('.semantic-form-item-title') + ).toContainText(DATA_CONTRACT_SEMANTICS1.name); + + // Save contract and validate for semantics - should fail initially + await saveAndTriggerDataContractValidation(page, true); + + await expect( + page.getByTestId('contract-status-card-item-semantics-status') + ).toContainText('Failed'); + await expect( + page.getByTestId('data-contract-latest-result-btn') + ).toContainText('Contract Failed'); + } + ); + + await testPersona.step( + 'Create Persona and assign user to it', + async () => { + await redirectToHomePage(page); + + const personaGetResponse = page.waitForResponse('/api/v1/personas**'); + await settingClick(page, GlobalSettingOptions.PERSONA); + await personaGetResponse; + + await page.waitForSelector('.ant-skeleton-content', { + state: 'detached', + }); + + // Navigate to persona details + await page + .getByTestId(`persona-details-card-${persona.data.name}`) + .click(); + await page.getByRole('tab', { name: 'Users' }).click(); + + // Add user to persona + await page.getByTestId('add-persona-button').click(); + await page.waitForSelector('[data-testid="loader"]', { + state: 'detached', + }); + + const searchUser = page.waitForResponse( + `/api/v1/search/query?q=*${encodeURIComponent( + adminUser.responseData.displayName + )}*` + ); + await page + .getByTestId('searchbar') + .fill(adminUser.responseData.displayName); + await searchUser; + + await page + .getByRole('listitem', { name: adminUser.responseData.displayName }) + .click(); + + const personaResponse = page.waitForResponse('/api/v1/personas/*'); + + await page.getByTestId('selectable-list-update-btn').click(); + await personaResponse; + } + ); + + await testPersona.step( + 'Verify Contract tab and status badge are visible if persona is set', + async () => { + await redirectToHomePage(page); + await table.visitEntityPage(page); + await page.waitForLoadState('networkidle'); + await page.waitForSelector('[data-testid="loader"]', { + state: 'detached', + }); + + // Verify Contract tab is not visible (should be hidden by persona customization) + await expect(page.getByTestId('contract')).toBeVisible(); + + // Verify Contract status badge is not visible in header + await expect( + page.getByTestId('data-contract-latest-result-btn') + ).toBeVisible(); + + // Additional verification: Check that other tabs are still visible + await expect(page.getByTestId('schema')).toBeVisible(); + await expect(page.getByTestId('activity_feed')).toBeVisible(); + await expect(page.getByTestId('sample_data')).toBeVisible(); + await expect(page.getByTestId('table_queries')).toBeVisible(); + await expect(page.getByTestId('profiler')).toBeVisible(); + await expect(page.getByTestId('lineage')).toBeVisible(); + await expect(page.getByTestId('custom_properties')).toBeVisible(); + } + ); + + await testPersona.step( + 'Customize Table page to hide Contract tab', + async () => { + await settingClick(page, GlobalSettingOptions.PERSONA); + await page.waitForLoadState('networkidle'); + await page.waitForSelector('[data-testid="loader"]', { + state: 'detached', + }); + + // Navigate to persona details and customize UI + await page + .getByTestId(`persona-details-card-${persona.data.name}`) + .click(); + await page.getByRole('tab', { name: 'Customize UI' }).click(); + await page.waitForLoadState('networkidle'); + + // Navigate to Table customization + await page + .getByTestId('data-assets') + .getByText('Data Assets') + .click(); + await page.getByText('Table', { exact: true }).click(); + + await page.waitForSelector('[data-testid="loader"]', { + state: 'detached', + }); + + // Hide the Contract tab + await page.getByTestId('tab-contract').click(); + await page.getByText('Hide', { exact: true }).click(); + + // Save the customization + await page.getByTestId('save-button').click(); + await toastNotification( + page, + /^Page layout (created|updated) successfully\.$/ + ); + } + ); + + await testPersona.step( + 'Verify Contract tab and status badge are hidden after persona customization', + async () => { + // After applying persona customization to hide the contract tab, + // we need to verify that the contract tab and status badge are not visible + // when viewing the table page with the customized persona. + + await redirectToHomePage(page); + await table.visitEntityPage(page); + await page.waitForLoadState('networkidle'); + await page.waitForSelector('[data-testid="loader"]', { + state: 'detached', + }); + + // Verify Contract tab is not visible (should be hidden by persona customization) + await expect(page.getByTestId('contract')).not.toBeVisible(); + + // Verify Contract status badge is not visible in header + await expect( + page.getByTestId('data-contract-latest-result-btn') + ).not.toBeVisible(); + + // Additional verification: Check that other tabs are still visible + await expect(page.getByTestId('schema')).toBeVisible(); + await expect(page.getByTestId('activity_feed')).toBeVisible(); + await expect(page.getByTestId('sample_data')).toBeVisible(); + await expect(page.getByTestId('table_queries')).toBeVisible(); + await expect(page.getByTestId('profiler')).toBeVisible(); + await expect(page.getByTestId('lineage')).toBeVisible(); + await expect(page.getByTestId('custom_properties')).toBeVisible(); + } + ); + } + ); +}); diff --git a/openmetadata-ui/src/main/resources/ui/playwright/utils/advancedSearch.ts b/openmetadata-ui/src/main/resources/ui/playwright/utils/advancedSearch.ts index 77c1d09ff5f..941d8a84933 100644 --- a/openmetadata-ui/src/main/resources/ui/playwright/utils/advancedSearch.ts +++ b/openmetadata-ui/src/main/resources/ui/playwright/utils/advancedSearch.ts @@ -187,10 +187,18 @@ export const selectOption = async ( .locator('.ant-select-selector') .click({ force: true }); + await page.waitForSelector('.ant-select-item-empty', { + state: 'detached', + }); + // Clear any existing input and type the new value const combobox = dropdownLocator.getByRole('combobox'); await combobox.clear(); await combobox.fill(optionTitle); + + await page.waitForSelector('.ant-select-item-empty', { + state: 'detached', + }); } else { await dropdownLocator.click(); }