Skip to content

Commit f7937e7

Browse files
0marSalahdmitrizagidulin
authored andcommitted
refactor: enhance wait logic in recommendation creation tests for better CI stability
1 parent ec10563 commit f7937e7

1 file changed

Lines changed: 26 additions & 12 deletions

File tree

e2e/recommendation-creation.spec.ts

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,21 @@
11
import { test, expect } from '@playwright/test';
22

3-
// Helper: wait for the recommendation page to finish loading (spinner gone)
3+
// Helper: wait for the recommendation page to finish loading (spinner gone) and reach a terminal state.
4+
// In CI, hydration and network can be slow, so we wait for form, error, or step-0 UI to appear.
45
async function waitForPageReady(page: any): Promise<void> {
56
const spinner = page.locator('[role="progressbar"]');
67
await spinner.waitFor({ state: 'hidden', timeout: 30000 }).catch(() => {});
7-
// Extra buffer for client hydration
8-
await page.waitForTimeout(1000);
8+
const readyTimeout = process.env.CI ? 20000 : 5000;
9+
const deadline = Date.now() + readyTimeout;
10+
while (Date.now() < deadline) {
11+
const hasError = await isErrorState(page);
12+
if (hasError) return;
13+
const hasForm = await page.locator('form').first().isVisible().catch(() => false);
14+
if (hasForm) return;
15+
const hasStep0 = await page.getByRole('button', { name: /continue without saving|login.*google.*drive/i }).first().isVisible().catch(() => false);
16+
if (hasStep0) return;
17+
await page.waitForTimeout(400);
18+
}
919
}
1020

1121
// Helper: check if page landed in an error/empty state (expected with fake IDs)
@@ -29,11 +39,12 @@ test.describe('Recommendation Creation', () => {
2939
await expect(page).toHaveURL(/.*recommendations.*/);
3040

3141
// With a fake ID the page will either show the form or an error — both are valid.
32-
// Just verify something rendered after the spinner disappeared.
33-
const hasError = await isErrorState(page);
34-
const hasForm = await page.locator('form').first().isVisible().catch(() => false);
35-
36-
expect(hasError || hasForm).toBeTruthy();
42+
// Poll for terminal state so CI (slower hydration) doesn't flake.
43+
await expect(async () => {
44+
const hasError = await isErrorState(page);
45+
const hasForm = await page.locator('form').first().isVisible().catch(() => false);
46+
expect(hasError || hasForm).toBeTruthy();
47+
}).toPass({ timeout: process.env.CI ? 15000 : 5000 });
3748
});
3849

3950
test('can navigate through form steps', async ({ page }) => {
@@ -63,11 +74,14 @@ test.describe('Recommendation Creation', () => {
6374
const googleDriveButton = page.getByRole('button', { name: /login.*google.*drive/i });
6475
const continueWithoutSaving = page.getByRole('button', { name: /continue without saving/i });
6576

66-
const hasGoogleButton = await googleDriveButton.isVisible({ timeout: 5000 }).catch(() => false);
67-
const hasContinueButton = await continueWithoutSaving.isVisible({ timeout: 5000 }).catch(() => false);
68-
69-
expect(hasGoogleButton || hasContinueButton).toBeTruthy();
77+
// Poll so CI (slower render) doesn't flake
78+
await expect(async () => {
79+
const hasGoogleButton = await googleDriveButton.isVisible({ timeout: 2000 }).catch(() => false);
80+
const hasContinueButton = await continueWithoutSaving.isVisible({ timeout: 2000 }).catch(() => false);
81+
expect(hasGoogleButton || hasContinueButton).toBeTruthy();
82+
}).toPass({ timeout: process.env.CI ? 15000 : 5000 });
7083

84+
const hasContinueButton = await continueWithoutSaving.isVisible({ timeout: 5000 }).catch(() => false);
7185
if (hasContinueButton) {
7286
await continueWithoutSaving.click();
7387
await page.waitForTimeout(1000);

0 commit comments

Comments
 (0)