Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
2979813
Fix bot name matching on the Bots page search
siddhiguptas Apr 14, 2026
a3d6165
Fixes #26970: migrate Bots search to API-based name/email lookup with…
siddhiguptas Apr 15, 2026
925d005
Fix flaky Playwright setup by making Table/User creation idempotent a…
siddhiguptas Apr 16, 2026
8ee2155
Merge branch 'main' into fix/bots-page-name-search
siddhiguptas Apr 16, 2026
9c0d085
Fixes #26970: avoid full bot scan by switching search result resoluti…
siddhiguptas Apr 16, 2026
f78b4f3
Merge branch 'fix/bots-page-name-search' of https://github.com/siddhi…
siddhiguptas Apr 16, 2026
339804f
Fixes #26970: align bot user search with deleted toggle and tighten t…
siddhiguptas Apr 16, 2026
324c3d6
Fixes #26970: keep bot search API-driven, align wildcard matching wit…
siddhiguptas Apr 17, 2026
2ed61b3
fix: stabilize bot search behavior and flaky Playwright flows across …
siddhiguptas Apr 17, 2026
2f6bbfc
fix: limit PR scope to bot search by reverting unrelated Tour Playwri…
siddhiguptas Apr 17, 2026
ac54692
Merge branch 'main' into fix/bots-page-name-search
harsh-vador Apr 17, 2026
ce64825
fix: remove unrelated Playwright changes and keep bot search scope fo…
siddhiguptas Apr 17, 2026
e8802bc
Merge branch 'fix/bots-page-name-search' of https://github.com/siddhi…
siddhiguptas Apr 17, 2026
774f59b
fix: optimize bot search scalability with paginated user-index retrie…
siddhiguptas Apr 18, 2026
392e98f
Merge branch 'main' into fix/bots-page-name-search
siddhiguptas Apr 18, 2026
d2e68dc
fix: harden Bots API search with bounded pagination/concurrency and c…
siddhiguptas Apr 18, 2026
0c150f5
Merge branch 'fix/bots-page-name-search' of https://github.com/siddhi…
siddhiguptas Apr 18, 2026
9bed9d3
fix: prevent stale bot search state and strengthen Bots Playwright co…
siddhiguptas Apr 18, 2026
8716fb2
test: scope Playwright fixes to bot flow and remove unrelated test ch…
siddhiguptas Apr 20, 2026
0956671
Add local bot search and stabilize tests
siddhiguptas Apr 20, 2026
edf3496
Fixes: keep Bot search API-driven for complete results and stabilize …
siddhiguptas Apr 20, 2026
1ec1666
chore: revert out-of-scope bot Playwright test changes
siddhiguptas Apr 20, 2026
d61e5df
test: add bot search e2e coverage and tighten bot API response assert…
siddhiguptas Apr 20, 2026
9482345
test: stabilize bot search no-match assertions using filter placehold…
siddhiguptas Apr 24, 2026
9b4f6c0
fix: add search API wait in bot Playwright flow and refactor bot-user…
siddhiguptas Apr 24, 2026
eac9242
fix: extract reusable searchbar helper with search API wait and dedup…
siddhiguptas Apr 24, 2026
d43b9db
Merge branch 'main' into fix/bots-page-name-search
siddhiguptas Apr 24, 2026
6d254bc
Merge branch 'main' into fix/bots-page-name-search
harsh-vador Apr 26, 2026
0d75ae2
fix(playwright): make bot search test stable by removing brittle API …
siddhiguptas Apr 29, 2026
08c3f0f
Merge branch 'fix/bots-page-name-search' of https://github.com/siddhi…
siddhiguptas Apr 29, 2026
13fbb21
Refactor bot search integration and Playwright synchronization for re…
siddhiguptas Apr 30, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
tokenExpirationForDays,
tokenExpirationUnlimitedDays,
updateBotDetails,
verifyBotSearch,
verifyGenerateTokenAPIContract,
} from '../../utils/bot';

Expand Down Expand Up @@ -48,6 +49,10 @@ test.describe(
await updateBotDetails(page);
});

await test.step('Verify bot search works by name and email', async () => {
await verifyBotSearch(page);
});

await test.step('Verify generateToken API contract', async () => {
await verifyGenerateTokenAPIContract(page);
});
Expand Down
45 changes: 42 additions & 3 deletions openmetadata-ui/src/main/resources/ui/playwright/utils/bot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ import { GlobalSettingOptions } from '../constant/settings';
import {
descriptionBox,
redirectToHomePage,
searchFromSearchInput,
toastNotification,
updateSearchInputAndWait,
uuid,
} from './common';
import { customFormatDateTime, getEpochMillisForFutureDays } from './dateTime';
Expand Down Expand Up @@ -70,9 +72,15 @@ export const createBot = async (page: Page) => {

await page.locator(descriptionBox).fill(BOT_DETAILS.description);

const saveResponse = page.waitForResponse('/api/v1/bots');
const saveResponse = page.waitForResponse(
(response) =>
response.url().includes('/api/v1/bots') &&
response.request().method() === 'POST'
);
await page.click('[data-testid="save-user"]');
await saveResponse;
const createBotResponse = await saveResponse;

expect(createBotResponse.status()).toBe(201);

// Verify bot is getting added in the bots listing page
await expect(
Expand Down Expand Up @@ -115,7 +123,10 @@ export const deleteBot = async (page: Page) => {

await toastNotification(page, /deleted successfully!/);

await expect(page.locator('.ant-table-tbody')).not.toContainText(botName);
await page.getByTestId('searchbar').clear();
await page.getByTestId('searchbar').fill(BOT_DETAILS.updatedBotName);
Comment thread
siddhiguptas marked this conversation as resolved.
await waitForAllLoadersToDisappear(page);
await expect(page.getByTestId('search-error-placeholder')).toBeVisible();
};

export const updateBotDetails = async (page: Page) => {
Expand Down Expand Up @@ -154,6 +165,34 @@ export const updateBotDetails = async (page: Page) => {
).toContainText(BOT_DETAILS.updatedDescription);
};

export const verifyBotSearch = async (page: Page) => {
const searchInput = page.getByTestId('searchbar');
const createdBotLink = page.getByTestId(
`bot-link-${BOT_DETAILS.updatedBotName}`
);

await searchFromSearchInput(page, searchInput, BOT_DETAILS.updatedBotName, {
waitForSearchApi: true,
});
await expect(createdBotLink).toBeVisible();

await searchFromSearchInput(page, searchInput, BOT_DETAILS.botEmail, {
waitForSearchApi: true,
});
await expect(createdBotLink).toBeVisible();

await searchFromSearchInput(
page,
searchInput,
`${BOT_DETAILS.updatedBotName}-no-match`,
{ waitForSearchApi: true }
);
await expect(page.getByTestId('search-error-placeholder')).toBeVisible();

await updateSearchInputAndWait(page, searchInput, '');
await expect(createdBotLink).toBeVisible();
};

export const tokenExpirationForDays = async (page: Page) => {
await getCreatedBot(page, {
botName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,52 @@ export const clickOutside = async (page: Page) => {
});
};

export const updateSearchInputAndWait = async (
page: Page,
searchInput: Locator,
value: string
) => {
await searchInput.clear();
await searchInput.fill(value);
await expect(searchInput).toHaveValue(value);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

integrate the search api get api here as well

await waitForAllLoadersToDisappear(page);
};

type SearchInputOptions = {
waitForSearchApi?: boolean;
searchApiPattern?: string;
};

export const searchFromSearchInput = async (
page: Page,
searchInput: Locator,
searchTerm: string,
options: SearchInputOptions = {}
) => {
const {
waitForSearchApi = false,
searchApiPattern = '/api/v1/search/query',
} = options;

const searchResponsePromise = waitForSearchApi
? page.waitForResponse(
(response) =>
response.url().includes(searchApiPattern) &&
response.request().method() === 'GET' &&
response.url().includes(encodeURIComponent(searchTerm))
)
Comment on lines +228 to +234
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Edge Case: searchFromSearchInput waits on API even for empty search term

The old code guarded waitForResponse with waitForSearchApi && searchTerm. The new code (line 228) only checks waitForSearchApi. When searchTerm is empty, encodeURIComponent('') is '', and url.includes('') is always true, so the promise will match the first GET to the search API pattern regardless of query content. This is unlikely to cause failures in current callers (all pass non-empty terms), but it weakens the assertion and could cause flaky matches if the helper is reused with an empty term in the future.

Was this helpful? React with 👍 / 👎 | Reply gitar fix to apply this suggestion

: undefined;

await updateSearchInputAndWait(page, searchInput, searchTerm);

if (!searchResponsePromise) {
return;
}

const searchResponse = await searchResponsePromise;
expect(searchResponse.status()).toBe(200);
};

export const visitOwnProfilePage = async (page: Page) => {
await page.locator('[data-testid="dropdown-profile"] svg').click();
await page.locator('[role="menu"].profile-dropdown').waitFor({
Expand Down
Loading
Loading