mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-04 09:13:08 +00:00
fix: add retry mechanisms to context test helpers for flaky test stability
Update waitForContextFile, selectContextFile, and waitForFileContentToLoad helpers to use Playwright's expect().toPass() with retry intervals, handling race conditions between API calls completing and UI re-rendering. Also add waitForNetworkIdle after dialog closes in context-file-management test.
This commit is contained in:
@@ -50,7 +50,8 @@ test.describe('Context File Management', () => {
|
|||||||
{ timeout: 5000 }
|
{ 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');
|
const fileButton = await getByTestId(page, 'context-file-test-context.md');
|
||||||
await expect(fileButton).toBeVisible();
|
await expect(fileButton).toBeVisible();
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ test.describe('Delete Context File', () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Wait for the file to appear in the list
|
// Wait for the file to appear in the list
|
||||||
await waitForContextFile(page, fileName, 10000);
|
await waitForContextFile(page, fileName);
|
||||||
|
|
||||||
// Select the file
|
// Select the file
|
||||||
await selectContextFile(page, fileName);
|
await selectContextFile(page, fileName);
|
||||||
|
|||||||
@@ -114,47 +114,51 @@ export async function toggleContextPreviewMode(page: Page): Promise<void> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Wait for a specific file to appear in the context file list
|
* 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(
|
export async function waitForContextFile(
|
||||||
page: Page,
|
page: Page,
|
||||||
filename: string,
|
filename: string,
|
||||||
timeout: number = 10000
|
timeout: number = 15000
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
|
await expect(async () => {
|
||||||
const locator = page.locator(`[data-testid="context-file-${filename}"]`);
|
const locator = page.locator(`[data-testid="context-file-${filename}"]`);
|
||||||
await locator.waitFor({ state: 'visible', timeout });
|
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)
|
* 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(
|
export async function selectContextFile(
|
||||||
page: Page,
|
page: Page,
|
||||||
filename: string,
|
filename: string,
|
||||||
timeout: number = 10000
|
timeout: number = 15000
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const fileButton = await getByTestId(page, `context-file-${filename}`);
|
const fileButton = await getByTestId(page, `context-file-${filename}`);
|
||||||
await fileButton.waitFor({ state: 'visible', timeout });
|
|
||||||
|
|
||||||
|
// Retry click + wait for delete button to handle timing issues
|
||||||
|
await expect(async () => {
|
||||||
// Use JavaScript click to ensure React onClick handler fires
|
// Use JavaScript click to ensure React onClick handler fires
|
||||||
await fileButton.evaluate((el) => (el as HTMLButtonElement).click());
|
await fileButton.evaluate((el) => (el as HTMLButtonElement).click());
|
||||||
|
|
||||||
// Wait for the file to be selected (toolbar with delete button becomes visible)
|
// Wait for the file to be selected (toolbar with delete button becomes visible)
|
||||||
const deleteButton = await getByTestId(page, 'delete-context-file');
|
const deleteButton = await getByTestId(page, 'delete-context-file');
|
||||||
await expect(deleteButton).toBeVisible({
|
await expect(deleteButton).toBeVisible();
|
||||||
timeout,
|
}).toPass({ timeout, intervals: [500, 1000, 2000] });
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wait for file content panel to load (either editor, preview, or image)
|
* 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<void> {
|
export async function waitForFileContentToLoad(page: Page, timeout: number = 15000): Promise<void> {
|
||||||
// Wait for either the editor, preview, or image to appear
|
await expect(async () => {
|
||||||
await page.waitForSelector(
|
const contentLocator = page.locator(
|
||||||
'[data-testid="context-editor"], [data-testid="markdown-preview"], [data-testid="image-preview"]',
|
'[data-testid="context-editor"], [data-testid="markdown-preview"], [data-testid="image-preview"]'
|
||||||
{ timeout: 10000 }
|
|
||||||
);
|
);
|
||||||
|
await expect(contentLocator).toBeVisible();
|
||||||
|
}).toPass({ timeout, intervals: [500, 1000, 2000] });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user