From 09ca9ab3d7ce44f0802a80f2441370c0bcc1b430 Mon Sep 17 00:00:00 2001 From: Karin Hendrikse <30577427+khendrikse@users.noreply.github.com> Date: Fri, 17 Oct 2025 15:56:12 +0200 Subject: [PATCH 1/3] fix: try to improve deploy.test.ts --- .../commands/deploy/deploy.test.ts | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/tests/integration/commands/deploy/deploy.test.ts b/tests/integration/commands/deploy/deploy.test.ts index 0035de49922..03c3caf8ac8 100644 --- a/tests/integration/commands/deploy/deploy.test.ts +++ b/tests/integration/commands/deploy/deploy.test.ts @@ -824,14 +824,27 @@ describe.skipIf(process.env.NETLIFY_TEST_DISABLE_LIVE === 'true').concurrent('co true, )) as unknown as Deploy + // Add retry logic for fetching deployed functions + const fetchWithRetry = async (url: string, maxRetries = 5) => { + for (let i = 0; i < maxRetries; i++) { + try { + return await fetch(url) + } catch (error) { + if (i === maxRetries - 1) throw error + await pause(2000 * (i + 1)) // Exponential backoff: 2s, 4s, 6s, 8s + } + } + throw new Error(`Failed to fetch ${url} after ${maxRetries} retries`) + } + const [response1, response2, response3, response4, response5, response6, response7] = await Promise.all([ - fetch(`${deployUrl}/.netlify/functions/func-1`).then((res) => res.text()), - fetch(`${deployUrl}/.netlify/functions/func-2`).then((res) => res.text()), - fetch(`${deployUrl}/.netlify/functions/func-3`).then((res) => res.text()), - fetch(`${deployUrl}/.netlify/functions/func-4`), - fetch(`${deployUrl}/internal-v2-func`).then((res) => res.text()), - fetch(`${deployUrl}/framework-function-1`).then((res) => res.text()), - fetch(`${deployUrl}/framework-edge-function-1`).then((res) => res.text()), + fetchWithRetry(`${deployUrl}/.netlify/functions/func-1`).then((res) => res.text()), + fetchWithRetry(`${deployUrl}/.netlify/functions/func-2`).then((res) => res.text()), + fetchWithRetry(`${deployUrl}/.netlify/functions/func-3`).then((res) => res.text()), + fetchWithRetry(`${deployUrl}/.netlify/functions/func-4`), + fetchWithRetry(`${deployUrl}/internal-v2-func`).then((res) => res.text()), + fetchWithRetry(`${deployUrl}/framework-function-1`).then((res) => res.text()), + fetchWithRetry(`${deployUrl}/framework-edge-function-1`).then((res) => res.text()), ]) t.expect(response1).toEqual('User 1') From d1fd106fc96086aaef901f13edaa65b582230cc9 Mon Sep 17 00:00:00 2001 From: Karin Hendrikse <30577427+khendrikse@users.noreply.github.com> Date: Fri, 17 Oct 2025 16:18:19 +0200 Subject: [PATCH 2/3] chore: only do single threaded tests for win --- vitest.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vitest.config.ts b/vitest.config.ts index e2dc214919f..c2421a677c6 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -22,7 +22,7 @@ export default defineConfig({ pool: 'threads', poolOptions: { threads: { - singleThread: true, + singleThread: process.platform === 'win32', }, }, coverage: { From 3d60ff02271f8f198b58983dcfa5d179856aeb7e Mon Sep 17 00:00:00 2001 From: Karin Hendrikse <30577427+khendrikse@users.noreply.github.com> Date: Fri, 17 Oct 2025 16:33:21 +0200 Subject: [PATCH 3/3] fix: lets see if we improve nextjs windows issue --- tests/integration/utils/dev-server.ts | 21 ++++++++++++++++++--- vitest.config.ts | 6 ------ vitest.e2e.config.ts | 6 ------ 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/tests/integration/utils/dev-server.ts b/tests/integration/utils/dev-server.ts index d77ce42ebaa..302cd5fae80 100644 --- a/tests/integration/utils/dev-server.ts +++ b/tests/integration/utils/dev-server.ts @@ -71,7 +71,10 @@ const startServer = async ({ skipWaitPort = false, targetPort, }: DevServerOptions): Promise => { - const port = await getPort() + // Use worker-specific port ranges to avoid conflicts in parallel execution + const workerId = process.env.VITEST_WORKER_ID || '1' + const workerOffset = (parseInt(workerId) - 1) * 100 + const port = await getPort({ port: getPort.makeRange(3000 + workerOffset, 3000 + workerOffset + 99) }) const host = 'localhost' const url = `http://${host}:${port}` @@ -89,7 +92,8 @@ const startServer = async ({ if (targetPort) { baseArgs.push('--target-port', targetPort.toString()) } else { - const staticPort = await getPort() + // Use same worker-specific range for static port + const staticPort = await getPort({ port: getPort.makeRange(4000 + workerOffset, 4000 + workerOffset + 99) }) baseArgs.push('--staticServerPort', staticPort.toString()) } @@ -158,7 +162,18 @@ const startServer = async ({ }, close: async () => { selfKilled = true - await killProcess(ps) + // Enhanced cleanup for Windows to handle Next.js child processes + if (process.platform === 'win32' && ps.pid) { + try { + // Kill process tree on Windows to ensure all child processes are terminated + await execa('taskkill', ['/pid', ps.pid.toString(), '/T', '/F']) + } catch { + // Fallback to standard kill if taskkill fails + await killProcess(ps) + } + } else { + await killProcess(ps) + } }, promptHistory, }) diff --git a/vitest.config.ts b/vitest.config.ts index c2421a677c6..886c77a54e8 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -18,13 +18,7 @@ export default defineConfig({ escapeString: true, }, // Pin to vitest@1 behavior: https://vitest.dev/guide/migration.html#default-pool-is-forks. - // TODO(serhalp) Remove this and fix hanging `next-app-without-config` fixture on Windows. pool: 'threads', - poolOptions: { - threads: { - singleThread: process.platform === 'win32', - }, - }, coverage: { provider: 'v8', reporter: ['text', 'lcov'], diff --git a/vitest.e2e.config.ts b/vitest.e2e.config.ts index d70d20380f0..3979e3a4b2f 100644 --- a/vitest.e2e.config.ts +++ b/vitest.e2e.config.ts @@ -5,12 +5,6 @@ export default defineConfig({ include: ['e2e/**/*.e2e.[jt]s'], testTimeout: 1200_000, // Pin to vitest@1 behavior: https://vitest.dev/guide/migration.html#default-pool-is-forks. - // TODO(serhalp) Remove this and fix flaky hanging e2e tests on Windows. pool: 'threads', - poolOptions: { - threads: { - singleThread: true, - }, - }, }, })