From fc77100c3f09c3edfee4ecbc5c1d9cb02e3cf09d Mon Sep 17 00:00:00 2001 From: diegosouzapw Date: Tue, 2 Jun 2026 22:39:13 -0300 Subject: [PATCH] test: stabilize quota syncQuotaCombos shards + fix 2 e2e specs - quota-combo-balancing / quota-multiprovider: eliminate the per-test full SQLite migration (migrate once at module load; resetStorage now DELETEs rows instead of rmSync+re-migrate) so it no longer races --test-force-exit under concurrency; drain the fire-and-forget syncQuotaCombosGuarded dispatched by createPool/ updatePool (flushPendingSyncs via setImmediate) so assertions see deterministic combo state; assert the GROUP-slug combo name (combos are named by group, like quota-combo-groups) and seed the group. Validated on CI shards 5/8 + 8/8 (7 runs). - playground-compare: wait for CompareTab (dynamic import) to mount, and use expect().toBeVisible() instead of locator.isVisible() (which no longer waits in Playwright 1.50+). - group-b-quota-plans-config: drop the unreliable raw-HTML "500" substring check (Next.js chunk hashes contain "500"); keep the real error-boundary text check. --- tests/e2e/group-b-quota-plans-config.spec.ts | 8 +- tests/e2e/playground-compare.spec.ts | 21 +++- tests/unit/quota-combo-balancing.test.ts | 86 ++++++++++++---- tests/unit/quota-multiprovider.test.ts | 102 ++++++++++++++----- 4 files changed, 165 insertions(+), 52 deletions(-) diff --git a/tests/e2e/group-b-quota-plans-config.spec.ts b/tests/e2e/group-b-quota-plans-config.spec.ts index 58f322bc48..409e22eb9b 100644 --- a/tests/e2e/group-b-quota-plans-config.spec.ts +++ b/tests/e2e/group-b-quota-plans-config.spec.ts @@ -142,9 +142,13 @@ test.describe("Group B — Quota Plans Config", () => { await selector.selectOption({ label: /codex/i }); } - // After selection, the page should not be in a broken state + // After selection, the page should not be in a broken state. + // Note: page.content() includes the full HTML source, which contains Next.js + // chunk filenames — those hashes can legitimately contain the string "500". + // Checking for "500" in raw HTML is unreliable; instead check for the actual + // error boundary text that OmniRoute renders on unrecoverable errors + // (src/app/error.tsx heading: "Internal Server Error"). const pageContent = await page.content(); - expect(pageContent).not.toContain("500"); expect(pageContent).not.toContain("Internal Server Error"); }); }); diff --git a/tests/e2e/playground-compare.spec.ts b/tests/e2e/playground-compare.spec.ts index e9789f8d6c..9a1cc49c46 100644 --- a/tests/e2e/playground-compare.spec.ts +++ b/tests/e2e/playground-compare.spec.ts @@ -109,15 +109,30 @@ test.describe("Playground Compare Tab", () => { await expect(compareTab).toBeVisible({ timeout: 15000 }); await compareTab.click(); + // Wait for CompareTab to finish loading (it's a dynamic import with ssr: false). + // The "Add model column" button is always rendered once the component mounts and + // provides a reliable hydration signal before we check the Run/Cancel toolbar. + await expect(page.getByRole("button", { name: /add model/i })).toBeVisible({ + timeout: 10000, + }); + // The toolbar shows "Run all" when idle and "Cancel all" when streaming — // they are mutually exclusive. Verify the toolbar control is always present - // by checking that at least one of the two buttons is visible. + // by checking that exactly one of the two buttons is visible. // (CompareTab.tsx renders