From 8ad568bcf79ac2e79423c3381a30e37fd2c8f2d8 Mon Sep 17 00:00:00 2001 From: Rohit0301 Date: Thu, 23 Apr 2026 00:13:54 +0530 Subject: [PATCH 1/3] fix(advanced-search): move entityStatus to common config with hard-coded list values --- .../e2e/Features/AdvancedSearch.spec.ts | 364 ++++++++++++++++-- .../ui/playwright/utils/advancedSearch.ts | 24 ++ .../src/constants/AdvancedSearch.constants.ts | 2 +- .../ui/src/enums/AdvancedSearch.enum.ts | 2 +- .../src/utils/AdvancedSearchClassBase.test.ts | 5 +- .../ui/src/utils/AdvancedSearchClassBase.ts | 28 +- 6 files changed, 385 insertions(+), 40 deletions(-) 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 cad4edcb4524..d05f4e1275b5 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 @@ -11,9 +11,13 @@ * limitations under the License. */ +import { expect } from '@playwright/test'; +import { EntityStatus } from '../../../src/generated/entity/data/searchIndex'; import { COMMON_TIER_TAG } from '../../constant/common'; import { SidebarItem } from '../../constant/sidebar'; +import { DataProduct } from '../../support/domain/DataProduct'; import { EntityDataClass } from '../../support/entity/EntityDataClass'; +import { MlModelClass } from '../../support/entity/MlModelClass'; import { TableClass } from '../../support/entity/TableClass'; import { TopicClass } from '../../support/entity/TopicClass'; import { Glossary } from '../../support/glossary/Glossary'; @@ -23,11 +27,16 @@ import { performAdminLogin } from '../../utils/admin'; import { FIELDS, OPERATOR, + fillRule, + fillStaticListRule, runRuleGroupTests, runRuleGroupTestsWithNonExistingValue, + selectOption, + showAdvancedSearchDialog, verifyAllConditions, } from '../../utils/advancedSearch'; import { redirectToHomePage } from '../../utils/common'; +import { waitForAllLoadersToDisappear } from '../../utils/entity'; import { sidebarClick } from '../../utils/sidebar'; import { test } from '../fixtures/pages'; @@ -226,56 +235,90 @@ test.describe('Advanced Search', { tag: ['@advanced-search'] }, () => { table2.entityResponseData.columns[3].name, ], 'displayName.keyword': [ - table1.entityResponseData.displayName, - table2.entityResponseData.displayName, + table1.entityResponseData.displayName || '', + table2.entityResponseData.displayName || '', ], serviceType: [ - table1.serviceResponseData.serviceType, - topic1.serviceResponseData.serviceType, + (table1.serviceResponseData as unknown as Record) + .serviceType, + (topic1.serviceResponseData as unknown as Record) + .serviceType, ], 'messageSchema.schemaFields.name.keyword': [ - topic1.entityResponseData?.messageSchema.schemaFields[0].name, - topic2.entityResponseData?.messageSchema.schemaFields[1].name, + topic1.entityResponseData?.messageSchema?.schemaFields?.[0]?.name || '', + topic2.entityResponseData?.messageSchema?.schemaFields?.[1]?.name || '', ], 'dataModel.columns.name.keyword': [ - EntityDataClass.container1.entityResponseData.dataModel.columns[0].name, - EntityDataClass.container2.entityResponseData.dataModel.columns[1].name, + EntityDataClass.container1.entityResponseData.dataModel?.columns?.[0]?.name || '', + EntityDataClass.container2.entityResponseData.dataModel?.columns?.[1]?.name || '', ], dataModelType: [ - EntityDataClass.dashboard1.dataModelResponseData.dataModelType, - EntityDataClass.dashboard2.dataModelResponseData.dataModelType, + ( + EntityDataClass.dashboard1 + .dataModelResponseData as unknown as Record + ).dataModelType, + ( + EntityDataClass.dashboard2 + .dataModelResponseData as unknown as Record + ).dataModelType, ], 'fields.name.keyword': [ EntityDataClass.searchIndex1.entityResponseData.fields[1].name, EntityDataClass.searchIndex2.entityResponseData.fields[3].name, ], 'tasks.displayName.keyword': [ - EntityDataClass.pipeline1.entityResponseData.tasks[0].displayName, - EntityDataClass.pipeline2.entityResponseData.tasks[1].displayName, + ( + EntityDataClass.pipeline1 + .entityResponseData as unknown as Record + ).tasks[0].displayName, + ( + EntityDataClass.pipeline2 + .entityResponseData as unknown as Record + ).tasks[1].displayName, ], 'domains.displayName.keyword': [ EntityDataClass.domain1.responseData.displayName, EntityDataClass.domain2.responseData.displayName, ], 'responseSchema.schemaFields.name.keyword': [ - EntityDataClass.apiCollection1.apiEndpointResponseData.responseSchema - .schemaFields[0].name, - EntityDataClass.apiCollection2.apiEndpointResponseData.responseSchema - .schemaFields[1].name, + ( + EntityDataClass.apiCollection1 + .apiEndpointResponseData as unknown as Record< + string, + { schemaFields: { name: string }[] } + > + ).responseSchema.schemaFields[0].name, + ( + EntityDataClass.apiCollection2 + .apiEndpointResponseData as unknown as Record< + string, + { schemaFields: { name: string }[] } + > + ).responseSchema.schemaFields[1].name, ], 'requestSchema.schemaFields.name.keyword': [ - EntityDataClass.apiCollection1.apiEndpointResponseData.requestSchema - .schemaFields[0].name, - EntityDataClass.apiCollection2.apiEndpointResponseData.requestSchema - .schemaFields[1].name, + ( + EntityDataClass.apiCollection1 + .apiEndpointResponseData as unknown as Record< + string, + { schemaFields: { name: string }[] } + > + ).requestSchema.schemaFields[0].name, + ( + EntityDataClass.apiCollection2 + .apiEndpointResponseData as unknown as Record< + string, + { schemaFields: { name: string }[] } + > + ).requestSchema.schemaFields[1].name, ], 'name.keyword': [ table1.entityResponseData.name, table2.entityResponseData.name, ], 'project.keyword': [ - EntityDataClass.dashboardDataModel1.entityResponseData.project, - EntityDataClass.dashboardDataModel2.entityResponseData.project, + EntityDataClass.dashboardDataModel1.entityResponseData.project || '', + EntityDataClass.dashboardDataModel2.entityResponseData.project || '', ], entityStatus: ['Approved', 'In Review'], // Some common field value search criteria are causing problems in not equal filter tests @@ -337,3 +380,280 @@ test.describe('Advanced Search', { tag: ['@advanced-search'] }, () => { await runRuleGroupTestsWithNonExistingValue(page); }); }); + +const ENTITY_STATUSES = Object.values(EntityStatus); + +test.describe( + 'Advanced Search - Entity Status Filter', + { tag: ['@advanced-search', '@Discovery'] }, + () => { + // One distinct entity type per status to prove the filter works across entity types + const glossaryForStatus = new Glossary(); + const glossaryTermApproved = new GlossaryTerm(glossaryForStatus); + const mlModelDraft = new MlModelClass(); + const dataProductInReview = new DataProduct(); + + type StatusEntry = { + status: EntityStatus; + endpoint: string; + id: () => string; + displayName: () => string; + fqn: () => string; + }; + + let statusEntries: StatusEntry[]; + + test.beforeAll( + 'Create mixed entity types with distinct entity statuses', + async ({ browser }) => { + const { apiContext, afterAction } = await performAdminLogin(browser); + + await glossaryForStatus.create(apiContext); + await Promise.all([ + glossaryTermApproved.create(apiContext), + mlModelDraft.create(apiContext), + dataProductInReview.create(apiContext), + ]); + + statusEntries = [ + { + status: EntityStatus.Approved, + endpoint: 'glossaryTerms', + id: () => glossaryTermApproved.responseData.id, + displayName: () => glossaryTermApproved.data.displayName, + fqn: () => glossaryTermApproved.responseData.fullyQualifiedName, + }, + { + status: EntityStatus.Draft, + endpoint: 'mlmodels', + id: () => mlModelDraft.entityResponseData.id, + displayName: () => mlModelDraft.entity.displayName, + fqn: () => mlModelDraft.entityResponseData.fullyQualifiedName, + }, + { + status: EntityStatus.InReview, + endpoint: 'dataProducts', + id: () => dataProductInReview.responseData.id ?? '', + displayName: () => dataProductInReview.data.displayName, + fqn: () => + dataProductInReview.responseData.fullyQualifiedName ?? '', + }, + ]; + + // Patch entityStatus on each entity + await Promise.all( + statusEntries.map(({ id, status, endpoint }) => + apiContext.patch(`/api/v1/${endpoint}/${id()}`, { + data: [{ op: 'add', path: '/entityStatus', value: status }], + headers: { 'Content-Type': 'application/json-patch+json' }, + }) + ) + ); + + await afterAction(); + } + ); + + test.beforeEach(async ({ page }) => { + await redirectToHomePage(page); + await sidebarClick(page, SidebarItem.EXPLORE); + }); + + test('All entity status options are visible in the Status dropdown', async ({ + page, + }) => { + test.slow(); + + await test.step('Open advanced search dialog', async () => { + await showAdvancedSearchDialog(page); + }); + + await test.step('Select Status field and == operator', async () => { + const ruleLocator = page.locator('.rule').nth(0); + await selectOption( + page, + ruleLocator.locator('.rule--field .ant-select'), + 'Status', + true + ); + await selectOption( + page, + ruleLocator.locator('.rule--operator .ant-select'), + '==' + ); + }); + + await test.step('Open Status value dropdown and verify all hard-coded options appear', async () => { + const ruleLocator = page.locator('.rule').nth(0); + await ruleLocator.locator('.widget--widget > .ant-select').click(); + + const dropdown = page + .locator('.ant-select-dropdown') + .filter({ hasText: EntityStatus.Approved }) + .last(); + + await expect(dropdown).toBeVisible(); + + for (const status of ENTITY_STATUSES) { + await expect( + dropdown + .locator('.ant-select-item-option') + .filter({ hasText: new RegExp(`^${status}$`, 'i') }) + .first() + ).toBeVisible(); + } + }); + }); + + test('Filtering by status "==" shows matching entity and hides others across entity types', async ({ + page, + }) => { + test.slow(); + + for (const entry of statusEntries) { + const { status } = entry; + const matchedName = entry.displayName(); + + await test.step(`Apply Status == "${status}" AND Name == "${matchedName}"`, async () => { + await showAdvancedSearchDialog(page); + + await fillStaticListRule(page, { + fieldLabel: 'Status', + condition: '==', + value: status, + ruleIndex: 1, + }); + + await page.getByTestId('advanced-search-add-rule').nth(1).click(); + + await fillRule(page, { + condition: '==', + field: { id: 'Display Name', name: 'displayName.keyword' }, + searchCriteria: matchedName, + index: 2, + }); + + const searchRes = page.waitForResponse( + '/api/v1/search/query?*index=dataAsset*' + ); + await page.getByTestId('apply-btn').click(); + await searchRes; + await waitForAllLoadersToDisappear(page); + }); + + await test.step('Filter chip shows the applied status', async () => { + await expect( + page.getByTestId('advance-search-filter-container') + ).toContainText(`'${status}'`); + }); + + await test.step(`"${matchedName}" (${entry.endpoint}) is visible`, async () => { + await expect( + page.getByTestId(`table-data-card_${entry.fqn()}`) + ).toBeVisible(); + }); + + await test.step('Entities with other statuses are not in results', async () => { + const otherEntries = statusEntries.filter((e) => e.status !== status); + + for (const other of otherEntries) { + await expect( + page.getByTestId(`table-data-card_${other.fqn()}`) + ).not.toBeVisible(); + } + }); + + await page.getByTestId('clear-filters').click(); + } + }); + + test('Filtering by status "!=" excludes matched entity but shows all other entity types', async ({ + page, + }) => { + test.slow(); + + const targetEntry = statusEntries.find( + (e) => e.status === EntityStatus.Approved + )!; + const approvedName = targetEntry.displayName(); + const otherEntries = statusEntries.filter( + (e) => e.status !== EntityStatus.Approved + ); + + await test.step('Apply Status != "Approved" AND Name == approved entity name', async () => { + await showAdvancedSearchDialog(page); + + await fillStaticListRule(page, { + fieldLabel: 'Status', + condition: '!=', + value: EntityStatus.Approved, + ruleIndex: 1, + }); + + await page.getByTestId('advanced-search-add-rule').nth(1).click(); + + await fillRule(page, { + condition: '==', + field: { id: 'Display Name', name: 'displayName.keyword' }, + searchCriteria: approvedName, + index: 2, + }); + + const searchRes = page.waitForResponse( + '/api/v1/search/query?*index=dataAsset*' + ); + await page.getByTestId('apply-btn').click(); + await searchRes; + await waitForAllLoadersToDisappear(page); + }); + + await test.step('Filter chip reflects the != condition', async () => { + await expect( + page.getByTestId('advance-search-filter-container') + ).toContainText(`'${EntityStatus.Approved}'`); + }); + + await test.step('GlossaryTerm with Approved status is not visible', async () => { + await expect( + page.getByTestId(`table-data-card_${targetEntry.fqn()}`) + ).not.toBeVisible(); + }); + + await test.step('Draft and In Review entities appear when searched by their name and non-Approved status', async () => { + for (const entry of otherEntries) { + await page.getByTestId('clear-filters').click(); + await showAdvancedSearchDialog(page); + + await fillStaticListRule(page, { + fieldLabel: 'Status', + condition: '!=', + value: EntityStatus.Approved, + ruleIndex: 1, + }); + + await page.getByTestId('advanced-search-add-rule').nth(1).click(); + + await fillRule(page, { + condition: '==', + field: { id: 'Display Name', name: 'displayName.keyword' }, + searchCriteria: entry.displayName(), + index: 2, + }); + + const searchRes = page.waitForResponse( + '/api/v1/search/query?*index=dataAsset*' + ); + await page.getByTestId('apply-btn').click(); + await searchRes; + await waitForAllLoadersToDisappear(page); + + await expect( + page.getByTestId(`table-data-card_${entry.fqn()}`) + ).toBeVisible(); + } + }); + + await page.getByTestId('clear-filters').click(); + }); + } +); 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 c6c62b05b375..cd99b794cb11 100644 --- a/openmetadata-ui/src/main/resources/ui/playwright/utils/advancedSearch.ts +++ b/openmetadata-ui/src/main/resources/ui/playwright/utils/advancedSearch.ts @@ -702,6 +702,30 @@ export const runRuleGroupTestsWithNonExistingValue = async (page: Page) => { await expect(dropdownText).not.toContainText('Loading...'); }; +// For fields backed by hard-coded listValues (no aggregate API call), options are +// rendered immediately — use selectOption directly instead of fillRule which waits +// for a network response that never comes. +export const fillStaticListRule = async ( + page: Page, + { + fieldLabel, + condition, + value, + ruleIndex, + }: { + fieldLabel: string; + condition: string; + value: string; + ruleIndex: number; + } +) => { + const ruleLocator = page.locator('.rule').nth(ruleIndex - 1); + + await selectOption(page, ruleLocator.locator('.rule--field .ant-select'), fieldLabel, true); + await selectOption(page, ruleLocator.locator('.rule--operator .ant-select'), condition); + await selectOption(page, ruleLocator.locator('.widget--widget > .ant-select'), value); +}; + export const getFieldsSuggestionSearchText = ( fieldLabel: string, data: Record diff --git a/openmetadata-ui/src/main/resources/ui/src/constants/AdvancedSearch.constants.ts b/openmetadata-ui/src/main/resources/ui/src/constants/AdvancedSearch.constants.ts index 0d9b17054288..dffbf5a6986a 100644 --- a/openmetadata-ui/src/main/resources/ui/src/constants/AdvancedSearch.constants.ts +++ b/openmetadata-ui/src/main/resources/ui/src/constants/AdvancedSearch.constants.ts @@ -215,7 +215,7 @@ export const GLOSSARY_DROPDOWN_ITEMS = [ }, { label: 'label.status', - key: EntityFields.GLOSSARY_TERM_STATUS, + key: EntityFields.ENTITY_STATUS, }, ]; diff --git a/openmetadata-ui/src/main/resources/ui/src/enums/AdvancedSearch.enum.ts b/openmetadata-ui/src/main/resources/ui/src/enums/AdvancedSearch.enum.ts index 7806809d853e..6d5e025eb082 100644 --- a/openmetadata-ui/src/main/resources/ui/src/enums/AdvancedSearch.enum.ts +++ b/openmetadata-ui/src/main/resources/ui/src/enums/AdvancedSearch.enum.ts @@ -75,7 +75,7 @@ export enum EntityFields { API_COLLECTION = 'apiCollection.displayName.keyword', CHART = 'charts.displayName.keyword', TASK = 'tasks.displayName.keyword', - GLOSSARY_TERM_STATUS = 'entityStatus', + ENTITY_STATUS = 'entityStatus', REQUEST_SCHEMA_FIELD = 'requestSchema.schemaFields.name.keyword', RESPONSE_SCHEMA_FIELD = 'responseSchema.schemaFields.name.keyword', SERVICE_NAME = 'service.name.keyword', diff --git a/openmetadata-ui/src/main/resources/ui/src/utils/AdvancedSearchClassBase.test.ts b/openmetadata-ui/src/main/resources/ui/src/utils/AdvancedSearchClassBase.test.ts index 286eae3812e9..1d224f7abb8c 100644 --- a/openmetadata-ui/src/main/resources/ui/src/utils/AdvancedSearchClassBase.test.ts +++ b/openmetadata-ui/src/main/resources/ui/src/utils/AdvancedSearchClassBase.test.ts @@ -177,10 +177,7 @@ describe('getEntitySpecificQueryBuilderFields', () => { SearchIndex.GLOSSARY_TERM, ]); - expect(Object.keys(result)).toEqual([ - EntityFields.GLOSSARY_TERM_STATUS, - EntityFields.GLOSSARY, - ]); + expect(Object.keys(result)).toEqual([EntityFields.GLOSSARY]); }); it('should return databaseSchema specific fields', () => { 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 6720080e9fb1..b55708d3140e 100644 --- a/openmetadata-ui/src/main/resources/ui/src/utils/AdvancedSearchClassBase.ts +++ b/openmetadata-ui/src/main/resources/ui/src/utils/AdvancedSearchClassBase.ts @@ -43,6 +43,7 @@ import { } from '../enums/AdvancedSearch.enum'; import { SearchIndex } from '../enums/search.enum'; import { Config } from '../generated/api/data/createCustomProperty'; +import { EntityStatus } from '../generated/entity/data/searchIndex'; import { CustomPropertySummary } from '../rest/metadataTypeAPI.interface'; import { getAggregateFieldOptions } from '../rest/miscAPI'; import { @@ -433,18 +434,6 @@ class AdvancedSearchClassBase { * Fields specific to Glossary */ glossaryTermQueryBuilderFields: Fields = { - [EntityFields.GLOSSARY_TERM_STATUS]: { - label: t('label.status'), - type: 'select', - mainWidgetProps: this.mainWidgetProps, - fieldSettings: { - asyncFetch: this.autocomplete({ - searchIndex: SearchIndex.GLOSSARY_TERM, - entityField: EntityFields.GLOSSARY_TERM_STATUS, - }), - useAsyncSearch: true, - }, - }, [EntityFields.GLOSSARY]: { label: t('label.glossary'), type: 'select', @@ -1048,6 +1037,21 @@ class AdvancedSearchClassBase { useAsyncSearch: true, }, }, + [EntityFields.ENTITY_STATUS]: { + label: t('label.status'), + type: 'select', + operators: LIST_VALUE_OPERATORS, + mainWidgetProps: this.mainWidgetProps, + valueSources: ['value'], + fieldSettings: { + listValues: Object.values(EntityStatus).map((status) => ({ + value: status, + title: status, + })), + showSearch: true, + useAsyncSearch: false, + }, + }, }; } From b80b63a7cc4d463d4342e8b67cdb8e138fd9376d Mon Sep 17 00:00:00 2001 From: Rohit0301 Date: Thu, 23 Apr 2026 12:37:08 +0530 Subject: [PATCH 2/3] lint and unit test fix --- .../e2e/Features/AdvancedSearch.spec.ts | 32 ++++++++++++------- .../ui/playwright/utils/advancedSearch.ts | 19 +++++++++-- .../src/utils/AdvancedSearchClassBase.test.ts | 1 + 3 files changed, 38 insertions(+), 14 deletions(-) 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 d05f4e1275b5..a014e3479e87 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 @@ -26,9 +26,9 @@ import { UserClass } from '../../support/user/UserClass'; import { performAdminLogin } from '../../utils/admin'; import { FIELDS, - OPERATOR, fillRule, fillStaticListRule, + OPERATOR, runRuleGroupTests, runRuleGroupTestsWithNonExistingValue, selectOption, @@ -249,17 +249,23 @@ test.describe('Advanced Search', { tag: ['@advanced-search'] }, () => { topic2.entityResponseData?.messageSchema?.schemaFields?.[1]?.name || '', ], 'dataModel.columns.name.keyword': [ - EntityDataClass.container1.entityResponseData.dataModel?.columns?.[0]?.name || '', - EntityDataClass.container2.entityResponseData.dataModel?.columns?.[1]?.name || '', + EntityDataClass.container1.entityResponseData.dataModel?.columns?.[0] + ?.name || '', + EntityDataClass.container2.entityResponseData.dataModel?.columns?.[1] + ?.name || '', ], dataModelType: [ ( - EntityDataClass.dashboard1 - .dataModelResponseData as unknown as Record + EntityDataClass.dashboard1.dataModelResponseData as unknown as Record< + string, + string + > ).dataModelType, ( - EntityDataClass.dashboard2 - .dataModelResponseData as unknown as Record + EntityDataClass.dashboard2.dataModelResponseData as unknown as Record< + string, + string + > ).dataModelType, ], 'fields.name.keyword': [ @@ -268,12 +274,16 @@ test.describe('Advanced Search', { tag: ['@advanced-search'] }, () => { ], 'tasks.displayName.keyword': [ ( - EntityDataClass.pipeline1 - .entityResponseData as unknown as Record + EntityDataClass.pipeline1.entityResponseData as unknown as Record< + string, + { displayName: string }[] + > ).tasks[0].displayName, ( - EntityDataClass.pipeline2 - .entityResponseData as unknown as Record + EntityDataClass.pipeline2.entityResponseData as unknown as Record< + string, + { displayName: string }[] + > ).tasks[1].displayName, ], 'domains.displayName.keyword': [ 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 cd99b794cb11..821dffac8dba 100644 --- a/openmetadata-ui/src/main/resources/ui/playwright/utils/advancedSearch.ts +++ b/openmetadata-ui/src/main/resources/ui/playwright/utils/advancedSearch.ts @@ -721,9 +721,22 @@ export const fillStaticListRule = async ( ) => { const ruleLocator = page.locator('.rule').nth(ruleIndex - 1); - await selectOption(page, ruleLocator.locator('.rule--field .ant-select'), fieldLabel, true); - await selectOption(page, ruleLocator.locator('.rule--operator .ant-select'), condition); - await selectOption(page, ruleLocator.locator('.widget--widget > .ant-select'), value); + await selectOption( + page, + ruleLocator.locator('.rule--field .ant-select'), + fieldLabel, + true + ); + await selectOption( + page, + ruleLocator.locator('.rule--operator .ant-select'), + condition + ); + await selectOption( + page, + ruleLocator.locator('.widget--widget > .ant-select'), + value + ); }; export const getFieldsSuggestionSearchText = ( diff --git a/openmetadata-ui/src/main/resources/ui/src/utils/AdvancedSearchClassBase.test.ts b/openmetadata-ui/src/main/resources/ui/src/utils/AdvancedSearchClassBase.test.ts index 1d224f7abb8c..c5eb1f61b55c 100644 --- a/openmetadata-ui/src/main/resources/ui/src/utils/AdvancedSearchClassBase.test.ts +++ b/openmetadata-ui/src/main/resources/ui/src/utils/AdvancedSearchClassBase.test.ts @@ -73,6 +73,7 @@ describe('AdvancedSearchClassBase', () => { 'tags.labelType', 'tier.labelType', 'createdBy', + EntityFields.ENTITY_STATUS, ]); }); }); From 524331ae03e5bfbf31eb8c293b27221fb19a84a0 Mon Sep 17 00:00:00 2001 From: Rohit0301 Date: Mon, 27 Apr 2026 12:09:20 +0530 Subject: [PATCH 3/3] addressed PR comment --- .../e2e/Features/AdvancedSearch.spec.ts | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) 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 c9dcde63d79b..67ac1b201fee 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 @@ -14,6 +14,7 @@ import { expect } from '@playwright/test'; import { EntityStatus } from '../../../src/generated/entity/data/searchIndex'; import { COMMON_TIER_TAG } from '../../constant/common'; +import { DOMAIN_TAGS } from '../../constant/config'; import { SidebarItem } from '../../constant/sidebar'; import { DataProduct } from '../../support/domain/DataProduct'; import { EntityDataClass } from '../../support/entity/EntityDataClass'; @@ -358,14 +359,8 @@ const ENTITY_STATUSES = Object.values(EntityStatus); test.describe( 'Advanced Search - Entity Status Filter', - { tag: ['@advanced-search', '@Discovery'] }, + { tag: [DOMAIN_TAGS.DISCOVERY] }, () => { - // One distinct entity type per status to prove the filter works across entity types - const glossaryForStatus = new Glossary(); - const glossaryTermApproved = new GlossaryTerm(glossaryForStatus); - const mlModelDraft = new MlModelClass(); - const dataProductInReview = new DataProduct(); - type StatusEntry = { status: EntityStatus; endpoint: string; @@ -374,6 +369,10 @@ test.describe( fqn: () => string; }; + let glossaryForStatus: Glossary; + let glossaryTermApproved: GlossaryTerm; + let mlModelDraft: MlModelClass; + let dataProductInReview: DataProduct; let statusEntries: StatusEntry[]; test.beforeAll( @@ -381,6 +380,11 @@ test.describe( async ({ browser }) => { const { apiContext, afterAction } = await performAdminLogin(browser); + glossaryForStatus = new Glossary(); + glossaryTermApproved = new GlossaryTerm(glossaryForStatus); + mlModelDraft = new MlModelClass(); + dataProductInReview = new DataProduct(); + await glossaryForStatus.create(apiContext); await Promise.all([ glossaryTermApproved.create(apiContext), @@ -435,8 +439,6 @@ test.describe( test('All entity status options are visible in the Status dropdown', async ({ page, }) => { - test.slow(); - await test.step('Open advanced search dialog', async () => { await showAdvancedSearchDialog(page); }); @@ -543,8 +545,6 @@ test.describe( test('Filtering by status "!=" excludes matched entity but shows all other entity types', async ({ page, }) => { - test.slow(); - const targetEntry = statusEntries.find( (e) => e.status === EntityStatus.Approved )!;