diff --git a/dev-packages/cloudflare-integration-tests/runner.ts b/dev-packages/cloudflare-integration-tests/runner.ts index 1b19e9e15efd..09bf18392609 100644 --- a/dev-packages/cloudflare-integration-tests/runner.ts +++ b/dev-packages/cloudflare-integration-tests/runner.ts @@ -20,7 +20,9 @@ process.on('exit', cleanupChildProcesses); // Wrangler can report "Ready" before it can actually handle requests. // This retries fetch on connection errors and transient 500 responses to handle this race condition. -async function fetchWithRetry(url: string, init: RequestInit, maxRetries = 10, retryDelayMs = 200): Promise { +// The budget (maxRetries * retryDelayMs) must cover the "ready-but-not-serving" window, which can be +// several seconds on a loaded CI runner — hence a generous default. +async function fetchWithRetry(url: string, init: RequestInit, maxRetries = 25, retryDelayMs = 200): Promise { for (let attempt = 0; attempt < maxRetries; attempt++) { try { const res = await fetch(url, init); diff --git a/dev-packages/cloudflare-integration-tests/vite.config.mts b/dev-packages/cloudflare-integration-tests/vite.config.mts index 10b3f319b762..a93b595b6ecd 100644 --- a/dev-packages/cloudflare-integration-tests/vite.config.mts +++ b/dev-packages/cloudflare-integration-tests/vite.config.mts @@ -10,7 +10,10 @@ export default defineConfig({ }, isolate: false, include: ['./suites/**/test.ts'], - testTimeout: 30_000, + // Each test spawns its own `wrangler dev` (cold workerd boot) and waits for envelopes to be + // delivered — there is no internal runner timeout, so this ceiling covers cold-start + async work + + // delivery. Cold-start is slow and highly variable on CI, so give it generous headroom to de-flake. + testTimeout: 60_000, // Ensure we can see debug output when DEBUG=true ...(process.env.DEBUG ? {