Skip to content

Commit ca2e015

Browse files
siddhant1Siddhantclaude
authored andcommitted
Fix: flaky domain rename data products count assertion (#26542)
* Fix: flaky domain rename data products count assertion After a domain rename, the search index update for subdomain-level data products can lag behind the DB update due to async reindexing by the governance-bot. The `verifyDataProductsCount` helper was doing a one-shot `textContent()` + `toBe()` assertion that failed when the search index hadn't converged yet. Changes: - Update `verifyDataProductsCount` to accept optional `{ apiContext, domainFqn }` that uses `expect.poll()` to poll the data product search API until `hits.total.value` matches the expected count (following the same pattern used in glossary.ts, alert.ts, and other polling utilities) - Switch from one-shot `toBe()` to auto-retrying `toHaveText()` for the UI check - Pass polling options in the post-rename assertion in Domains.spec.ts Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Add HTTP status check in search API poll Check response.ok() before parsing JSON in the expect.poll callback to avoid silently treating 4xx/5xx errors as count=0. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Remove custom timeout from toHaveText assertion The expect.poll already ensures the search index has converged before the UI check, so the default Playwright timeout is sufficient. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Siddhant <siddhant@MacBook-Pro-290.local> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> (cherry picked from commit 85ad580)
1 parent 5cd37e4 commit ca2e015

2 files changed

Lines changed: 56 additions & 5 deletions

File tree

openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/Domains.spec.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2035,7 +2035,11 @@ test.describe('Domain Rename Comprehensive Tests', () => {
20352035
);
20362036

20372037
// Verify data products count is preserved after rename
2038-
await verifyDataProductsCount(page, 2);
2038+
// Poll search API first since index may lag after domain rename
2039+
await verifyDataProductsCount(page, 2, {
2040+
apiContext,
2041+
domainFqn: newDomainName,
2042+
});
20392043

20402044
// Verify both data products are visible (scope to container)
20412045
const dataProductsContainer = page.locator('.explore-search-card');

openmetadata-ui/src/main/resources/ui/playwright/utils/domain.ts

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1338,22 +1338,69 @@ export const createDataProductForSubDomain = async (
13381338
/**
13391339
* Verifies the data products count displayed in the Data Products tab.
13401340
* Clicks on the Data Products tab and checks if the count matches the expected value.
1341+
* If apiContext and domainFqn are provided, polls the search API first to wait for
1342+
* index convergence (e.g. after domain rename).
13411343
*/
13421344
export const verifyDataProductsCount = async (
13431345
page: Page,
1344-
expectedCount: number
1346+
expectedCount: number,
1347+
options?: { apiContext: APIRequestContext; domainFqn: string }
13451348
) => {
1349+
if (options) {
1350+
const { apiContext, domainFqn } = options;
1351+
const queryFilter = JSON.stringify({
1352+
query: {
1353+
bool: {
1354+
must: [
1355+
{
1356+
bool: {
1357+
should: [
1358+
{ term: { 'domains.fullyQualifiedName': domainFqn } },
1359+
{
1360+
prefix: {
1361+
'domains.fullyQualifiedName': `${domainFqn}.`,
1362+
},
1363+
},
1364+
],
1365+
},
1366+
},
1367+
],
1368+
},
1369+
},
1370+
});
1371+
const searchUrl = `/api/v1/search/query?q=&index=data_product_search_index&from=0&size=0&deleted=false&query_filter=${encodeURIComponent(queryFilter)}`;
1372+
1373+
await expect
1374+
.poll(
1375+
async () => {
1376+
const response = await apiContext.get(searchUrl);
1377+
1378+
if (!response.ok()) {
1379+
return -1;
1380+
}
1381+
1382+
const data = await response.json();
1383+
1384+
return data.hits?.total?.value ?? 0;
1385+
},
1386+
{
1387+
message: `Wait for data product search index to show ${expectedCount} results for domain "${domainFqn}"`,
1388+
timeout: 30_000,
1389+
intervals: [2_000, 3_000, 5_000],
1390+
}
1391+
)
1392+
.toEqual(expectedCount);
1393+
}
1394+
13461395
await page.getByTestId('data_products').click();
13471396
await waitForAllLoadersToDisappear(page);
13481397
await page.waitForLoadState('networkidle');
13491398

13501399
const dataProductCountElement = page
13511400
.getByTestId('data_products')
13521401
.getByTestId('count');
1353-
const countText = await dataProductCountElement.textContent();
1354-
const displayedCount = parseInt(countText ?? '0', 10);
13551402

1356-
expect(displayedCount).toBe(expectedCount);
1403+
await expect(dataProductCountElement).toHaveText(String(expectedCount));
13571404
};
13581405

13591406
/**

0 commit comments

Comments
 (0)