diff --git a/apps/ui/tests/context/context-file-management.spec.ts b/apps/ui/tests/context/context-file-management.spec.ts index 220b345d..cef8a212 100644 --- a/apps/ui/tests/context/context-file-management.spec.ts +++ b/apps/ui/tests/context/context-file-management.spec.ts @@ -50,7 +50,8 @@ test.describe('Context File Management', () => { { timeout: 5000 } ); - await waitForContextFile(page, 'test-context.md', 10000); + await waitForNetworkIdle(page); + await waitForContextFile(page, 'test-context.md'); const fileButton = await getByTestId(page, 'context-file-test-context.md'); await expect(fileButton).toBeVisible(); diff --git a/apps/ui/tests/context/delete-context-file.spec.ts b/apps/ui/tests/context/delete-context-file.spec.ts index 0dc0ade5..4c4d8a53 100644 --- a/apps/ui/tests/context/delete-context-file.spec.ts +++ b/apps/ui/tests/context/delete-context-file.spec.ts @@ -53,7 +53,7 @@ test.describe('Delete Context File', () => { ); // Wait for the file to appear in the list - await waitForContextFile(page, fileName, 10000); + await waitForContextFile(page, fileName); // Select the file await selectContextFile(page, fileName); diff --git a/apps/ui/tests/utils/views/context.ts b/apps/ui/tests/utils/views/context.ts index 6254ebeb..6032e947 100644 --- a/apps/ui/tests/utils/views/context.ts +++ b/apps/ui/tests/utils/views/context.ts @@ -114,47 +114,51 @@ export async function toggleContextPreviewMode(page: Page): Promise { /** * Wait for a specific file to appear in the context file list + * Uses retry mechanism to handle race conditions with API/UI updates */ export async function waitForContextFile( page: Page, filename: string, - timeout: number = 10000 + timeout: number = 15000 ): Promise { - const locator = page.locator(`[data-testid="context-file-${filename}"]`); - await locator.waitFor({ state: 'visible', timeout }); + await expect(async () => { + const locator = page.locator(`[data-testid="context-file-${filename}"]`); + await expect(locator).toBeVisible(); + }).toPass({ timeout, intervals: [500, 1000, 2000] }); } /** * Click a file in the list and wait for it to be selected (toolbar visible) - * Uses JavaScript click to ensure React event handler fires + * Uses retry mechanism to handle race conditions where element is visible but not yet interactive */ export async function selectContextFile( page: Page, filename: string, - timeout: number = 10000 + timeout: number = 15000 ): Promise { const fileButton = await getByTestId(page, `context-file-${filename}`); - await fileButton.waitFor({ state: 'visible', timeout }); - // Use JavaScript click to ensure React onClick handler fires - await fileButton.evaluate((el) => (el as HTMLButtonElement).click()); - - // Wait for the file to be selected (toolbar with delete button becomes visible) - const deleteButton = await getByTestId(page, 'delete-context-file'); - await expect(deleteButton).toBeVisible({ - timeout, - }); + // Retry click + wait for delete button to handle timing issues + await expect(async () => { + // Use JavaScript click to ensure React onClick handler fires + await fileButton.evaluate((el) => (el as HTMLButtonElement).click()); + // Wait for the file to be selected (toolbar with delete button becomes visible) + const deleteButton = await getByTestId(page, 'delete-context-file'); + await expect(deleteButton).toBeVisible(); + }).toPass({ timeout, intervals: [500, 1000, 2000] }); } /** * Wait for file content panel to load (either editor, preview, or image) + * Uses retry mechanism to handle race conditions with file selection */ -export async function waitForFileContentToLoad(page: Page): Promise { - // Wait for either the editor, preview, or image to appear - await page.waitForSelector( - '[data-testid="context-editor"], [data-testid="markdown-preview"], [data-testid="image-preview"]', - { timeout: 10000 } - ); +export async function waitForFileContentToLoad(page: Page, timeout: number = 15000): Promise { + await expect(async () => { + const contentLocator = page.locator( + '[data-testid="context-editor"], [data-testid="markdown-preview"], [data-testid="image-preview"]' + ); + await expect(contentLocator).toBeVisible(); + }).toPass({ timeout, intervals: [500, 1000, 2000] }); } /**