diff --git a/openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/AdvancedSearch.spec.ts b/openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/AdvancedSearch.spec.ts index a15c6945bde..51dd9e555ec 100644 --- a/openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/AdvancedSearch.spec.ts +++ b/openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/AdvancedSearch.spec.ts @@ -22,6 +22,7 @@ import { FIELDS, OPERATOR, runRuleGroupTests, + runRuleGroupTestsWithNonExistingValue, verifyAllConditions, } from '../../utils/advancedSearch'; import { createNewPage, redirectToHomePage } from '../../utils/common'; @@ -287,4 +288,12 @@ test.describe('Advanced Search', { tag: '@advanced-search' }, () => { }); }); }); + + test('Verify search with non existing value do not result in infinite search', async ({ + page, + }) => { + test.slow(true); + + await runRuleGroupTestsWithNonExistingValue(page); + }); }); 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 8d8cf212c44..29682bc962c 100644 --- a/openmetadata-ui/src/main/resources/ui/playwright/utils/advancedSearch.ts +++ b/openmetadata-ui/src/main/resources/ui/playwright/utils/advancedSearch.ts @@ -581,3 +581,32 @@ export const runRuleGroupTests = async ( await page.getByTestId('clear-filters').click(); } }; + +export const runRuleGroupTestsWithNonExistingValue = async (page: Page) => { + await showAdvancedSearchDialog(page); + const ruleLocator = page.locator('.rule').nth(0); + + // Perform click on rule field + await selectOption( + page, + ruleLocator.locator('.rule--field .ant-select'), + 'Database' + ); + await selectOption( + page, + ruleLocator.locator('.rule--operator .ant-select'), + '==' + ); + + const inputElement = ruleLocator.locator( + '.rule--widget--SELECT .ant-select-selection-search-input' + ); + await inputElement.fill('non-existing-value'); + const dropdownText = page.locator('.ant-select-item-empty'); + + await expect(dropdownText).toContainText('Loading...'); + + await page.waitForTimeout(1000); + + await expect(dropdownText).not.toContainText('Loading...'); +}; diff --git a/openmetadata-ui/src/main/resources/ui/src/utils/AdvancedSearchClassBase.ts b/openmetadata-ui/src/main/resources/ui/src/utils/AdvancedSearchClassBase.ts index 622d680a5c6..5117d0c707a 100644 --- a/openmetadata-ui/src/main/resources/ui/src/utils/AdvancedSearchClassBase.ts +++ b/openmetadata-ui/src/main/resources/ui/src/utils/AdvancedSearchClassBase.ts @@ -137,8 +137,10 @@ class AdvancedSearchClassBase { entityField, isCaseInsensitive = false, }) => { - // Wrapping the fetch function in a debounce of 300 ms - const debouncedFetch = debounce((search, callback) => { + let pendingResolve: + | ((result: { values: any[]; hasMore: boolean }) => void) + | null = null; + const debouncedFetch = debounce((search: string) => { const sourceFields = isCaseInsensitive ? EntitySourceFields?.[entityField as EntityFields]?.join(',') : undefined; @@ -149,22 +151,40 @@ class AdvancedSearchClassBase { search ?? '', JSON.stringify(getCombinedQueryFilterObject()), sourceFields - ).then((response) => { - const buckets = - response.data.aggregations[`sterms#${entityField}`].buckets; + ) + .then((response) => { + const buckets = + response.data.aggregations[`sterms#${entityField}`].buckets; - const bucketsData = parseBucketsData(buckets, sourceFields); + const bucketsData = parseBucketsData(buckets, sourceFields); - callback({ - values: bucketsData, - hasMore: false, + if (pendingResolve) { + pendingResolve({ + values: bucketsData, + hasMore: false, + }); + pendingResolve = null; + } + }) + .catch(() => { + if (pendingResolve) { + pendingResolve({ + values: [], + hasMore: false, + }); + pendingResolve = null; + } }); - }); }, 300); return (search) => { return new Promise((resolve) => { - debouncedFetch(search, resolve); + // Resolve previous promise to prevent hanging + if (pendingResolve) { + pendingResolve({ values: [], hasMore: false }); + } + pendingResolve = resolve; + debouncedFetch(search ?? ''); }); }; };