From 628b6fb459526d4d668619b3c56e6290869f9212 Mon Sep 17 00:00:00 2001 From: Magnus Dahl Eide Date: Wed, 3 Sep 2025 19:52:17 +0200 Subject: [PATCH 1/6] fix(e2e): Ensure the response event listener is registered before navigation --- .../e2e/app-pages-router/app/ssg/page.tsx | 9 +++++++++ .../e2e/app-pages-router/e2e/headers.test.ts | 20 +++++++++++++++++++ .../app-router/e2e/middleware.rewrite.test.ts | 8 ++++---- examples/e2e/pages-router/e2e/header.test.ts | 2 ++ examples/e2e/pages-router/wrangler.jsonc | 5 ++++- 5 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 examples/e2e/app-pages-router/app/ssg/page.tsx create mode 100644 examples/e2e/app-pages-router/e2e/headers.test.ts diff --git a/examples/e2e/app-pages-router/app/ssg/page.tsx b/examples/e2e/app-pages-router/app/ssg/page.tsx new file mode 100644 index 00000000..7b76cfc1 --- /dev/null +++ b/examples/e2e/app-pages-router/app/ssg/page.tsx @@ -0,0 +1,9 @@ +export const dynamic = "force-static"; + +export default function Page() { + return ( +
+ This is a static page +
+ ); +} diff --git a/examples/e2e/app-pages-router/e2e/headers.test.ts b/examples/e2e/app-pages-router/e2e/headers.test.ts new file mode 100644 index 00000000..92a39083 --- /dev/null +++ b/examples/e2e/app-pages-router/e2e/headers.test.ts @@ -0,0 +1,20 @@ +import { expect, test } from "@playwright/test"; + +test("should test if poweredByHeader adds the correct headers ", async ({ page }) => { + const result = await page.goto("/ssg"); + expect(result).toBeDefined(); + expect(result?.status()).toBe(200); + const headers = result?.headers(); + + // This header should not be defined even when cache interception happens in the external middleware + expect(headers?.["x-opennext-requestid"]).toBeFalsy(); + + await page.waitForTimeout(2000); // Wait 2s + + const result2 = await page.goto("/ssg"); + expect(result2).toBeDefined(); + expect(result2?.status()).toBe(200); + const headers2 = result2?.headers(); + + expect(headers2?.["x-opennext-requestid"]).toBeFalsy(); +}); diff --git a/examples/e2e/app-router/e2e/middleware.rewrite.test.ts b/examples/e2e/app-router/e2e/middleware.rewrite.test.ts index 24c027b8..04ef4bea 100644 --- a/examples/e2e/app-router/e2e/middleware.rewrite.test.ts +++ b/examples/e2e/app-router/e2e/middleware.rewrite.test.ts @@ -23,7 +23,6 @@ test("Middleware Rewrite", async ({ page }) => { }); test("Middleware Rewrite External Image", async ({ page }) => { - await page.goto("/rewrite-external"); page.on("response", async (response) => { expect(response.status()).toBe(200); expect(response.headers()["content-type"]).toBe("image/png"); @@ -31,13 +30,14 @@ test("Middleware Rewrite External Image", async ({ page }) => { const bodyBuffer = await response.body(); expect(validateMd5(bodyBuffer, OPENNEXT_PNG_MD5)).toBe(true); }); + await page.goto("/rewrite-external"); }); test("Middleware Rewrite Status Code", async ({ page }) => { - await page.goto("/rewrite-status-code"); - const el = page.getByText("Rewritten Destination", { exact: true }); - await expect(el).toBeVisible(); page.on("response", async (response) => { expect(response.status()).toBe(403); }); + await page.goto("/rewrite-status-code"); + const el = page.getByText("Rewritten Destination", { exact: true }); + await expect(el).toBeVisible(); }); diff --git a/examples/e2e/pages-router/e2e/header.test.ts b/examples/e2e/pages-router/e2e/header.test.ts index 9c4e4f7c..4d28f6b9 100644 --- a/examples/e2e/pages-router/e2e/header.test.ts +++ b/examples/e2e/pages-router/e2e/header.test.ts @@ -9,4 +9,6 @@ test("should test if poweredByHeader adds the correct headers ", async ({ page } // Both these headers should be present cause poweredByHeader is true in pagesRouter expect(headers?.["x-powered-by"]).toBe("Next.js"); expect(headers?.["x-opennext"]).toBe("1"); + // This header should be defined cause we have set the `OPEN_NEXT_REQUEST_ID_HEADER` env variable in wrangler.jsonc + expect(headers?.["x-opennext-requestid"]).not.toBeFalsy(); }); diff --git a/examples/e2e/pages-router/wrangler.jsonc b/examples/e2e/pages-router/wrangler.jsonc index 6c5c5227..80f9372b 100644 --- a/examples/e2e/pages-router/wrangler.jsonc +++ b/examples/e2e/pages-router/wrangler.jsonc @@ -19,5 +19,8 @@ "binding": "WORKER_SELF_REFERENCE", "service": "pages-router" } - ] + ], + "vars": { + "OPEN_NEXT_REQUEST_ID_HEADER": "true" + } } From 44d2a060f76c3fda4656195c5675616c21e4c0e8 Mon Sep 17 00:00:00 2001 From: Magnus Dahl Eide Date: Thu, 4 Sep 2025 12:26:50 +0200 Subject: [PATCH 2/6] review --- examples/e2e/app-pages-router/e2e/headers.test.ts | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/examples/e2e/app-pages-router/e2e/headers.test.ts b/examples/e2e/app-pages-router/e2e/headers.test.ts index 92a39083..795352ae 100644 --- a/examples/e2e/app-pages-router/e2e/headers.test.ts +++ b/examples/e2e/app-pages-router/e2e/headers.test.ts @@ -1,20 +1,11 @@ import { expect, test } from "@playwright/test"; -test("should test if poweredByHeader adds the correct headers ", async ({ page }) => { +test("does not set x-opennext-requestid header on cache interceptor response", async ({ page }) => { const result = await page.goto("/ssg"); expect(result).toBeDefined(); expect(result?.status()).toBe(200); const headers = result?.headers(); - // This header should not be defined even when cache interception happens in the external middleware - expect(headers?.["x-opennext-requestid"]).toBeFalsy(); - - await page.waitForTimeout(2000); // Wait 2s - - const result2 = await page.goto("/ssg"); - expect(result2).toBeDefined(); - expect(result2?.status()).toBe(200); - const headers2 = result2?.headers(); - - expect(headers2?.["x-opennext-requestid"]).toBeFalsy(); + // This header should not be defined even when its a cached response from the cache interception in the external middleware + expect(headers?.["x-opennext-requestid"]).toBeUndefined(); }); From 439802ecf62f67f8338029ebb49eec1178ad3782 Mon Sep 17 00:00:00 2001 From: Magnus Dahl Eide Date: Thu, 4 Sep 2025 12:34:54 +0200 Subject: [PATCH 3/6] set toBeUndefined --- examples/e2e/pages-router/e2e/header.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/e2e/pages-router/e2e/header.test.ts b/examples/e2e/pages-router/e2e/header.test.ts index 4d28f6b9..6a2651b1 100644 --- a/examples/e2e/pages-router/e2e/header.test.ts +++ b/examples/e2e/pages-router/e2e/header.test.ts @@ -10,5 +10,5 @@ test("should test if poweredByHeader adds the correct headers ", async ({ page } expect(headers?.["x-powered-by"]).toBe("Next.js"); expect(headers?.["x-opennext"]).toBe("1"); // This header should be defined cause we have set the `OPEN_NEXT_REQUEST_ID_HEADER` env variable in wrangler.jsonc - expect(headers?.["x-opennext-requestid"]).not.toBeFalsy(); + expect(headers?.["x-opennext-requestid"]).not.toBeUndefined(); }); From d89bd7580369819e735a178395a5a6e23bebcb99 Mon Sep 17 00:00:00 2001 From: Magnus Dahl Eide Date: Fri, 5 Sep 2025 22:27:26 +0200 Subject: [PATCH 4/6] fix test --- examples/e2e/app-router/e2e/middleware.rewrite.test.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/e2e/app-router/e2e/middleware.rewrite.test.ts b/examples/e2e/app-router/e2e/middleware.rewrite.test.ts index 04ef4bea..ba314702 100644 --- a/examples/e2e/app-router/e2e/middleware.rewrite.test.ts +++ b/examples/e2e/app-router/e2e/middleware.rewrite.test.ts @@ -35,7 +35,11 @@ test("Middleware Rewrite External Image", async ({ page }) => { test("Middleware Rewrite Status Code", async ({ page }) => { page.on("response", async (response) => { - expect(response.status()).toBe(403); + // Need to set up the event before navigating to the page to avoid missing it + // We need to check the URL here also cause there will be multiple responses (i.e the fonts, css, js, etc) + if (response.url() === "/rewrite-status-code") { + expect(response.status()).toBe(403); + } }); await page.goto("/rewrite-status-code"); const el = page.getByText("Rewritten Destination", { exact: true }); From ba93b6df4624610ce9a418ce7b179e9b8eb2c6da Mon Sep 17 00:00:00 2001 From: Magnus Dahl Eide Date: Wed, 1 Oct 2025 13:50:06 +0200 Subject: [PATCH 5/6] fix test --- examples/e2e/app-router/e2e/middleware.rewrite.test.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/e2e/app-router/e2e/middleware.rewrite.test.ts b/examples/e2e/app-router/e2e/middleware.rewrite.test.ts index ba314702..f270e7e8 100644 --- a/examples/e2e/app-router/e2e/middleware.rewrite.test.ts +++ b/examples/e2e/app-router/e2e/middleware.rewrite.test.ts @@ -34,10 +34,11 @@ test("Middleware Rewrite External Image", async ({ page }) => { }); test("Middleware Rewrite Status Code", async ({ page }) => { + // Need to set up the event before navigating to the page to avoid missing it + // We need to check the URL here also cause there will be multiple responses (i.e the fonts, css, js, etc) page.on("response", async (response) => { - // Need to set up the event before navigating to the page to avoid missing it - // We need to check the URL here also cause there will be multiple responses (i.e the fonts, css, js, etc) - if (response.url() === "/rewrite-status-code") { + // `response.url()` will be the full URL including the host, so we need to check the pathname + if (new URL(response.url()).pathname === "/rewrite-status-code") { expect(response.status()).toBe(403); } }); From 5368399cbecad7c4388984e8953994f26e217579 Mon Sep 17 00:00:00 2001 From: Victor Berchet Date: Wed, 1 Oct 2025 14:14:41 +0200 Subject: [PATCH 6/6] fixup! ensure the event handler is called --- .../app-router/e2e/middleware.rewrite.test.ts | 35 ++++++++++++------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/examples/e2e/app-router/e2e/middleware.rewrite.test.ts b/examples/e2e/app-router/e2e/middleware.rewrite.test.ts index f270e7e8..c129d5cc 100644 --- a/examples/e2e/app-router/e2e/middleware.rewrite.test.ts +++ b/examples/e2e/app-router/e2e/middleware.rewrite.test.ts @@ -1,4 +1,4 @@ -import { expect, test } from "@playwright/test"; +import { expect, test, Response as PwResponse } from "@playwright/test"; import { validateMd5 } from "../../utils"; /* @@ -23,26 +23,37 @@ test("Middleware Rewrite", async ({ page }) => { }); test("Middleware Rewrite External Image", async ({ page }) => { - page.on("response", async (response) => { - expect(response.status()).toBe(200); - expect(response.headers()["content-type"]).toBe("image/png"); - expect(response.headers()["cache-control"]).toBe("max-age=600"); - const bodyBuffer = await response.body(); - expect(validateMd5(bodyBuffer, OPENNEXT_PNG_MD5)).toBe(true); + let responsePromise = new Promise((resolve) => { + page.on("response", async (resp) => { + resolve(resp); + }); }); + await page.goto("/rewrite-external"); + + const response = await responsePromise; + + expect(response.status()).toBe(200); + expect(response.headers()["content-type"]).toBe("image/png"); + expect(response.headers()["cache-control"]).toBe("max-age=600"); + const bodyBuffer = await response.body(); + expect(validateMd5(bodyBuffer, OPENNEXT_PNG_MD5)).toBe(true); }); test("Middleware Rewrite Status Code", async ({ page }) => { // Need to set up the event before navigating to the page to avoid missing it // We need to check the URL here also cause there will be multiple responses (i.e the fonts, css, js, etc) - page.on("response", async (response) => { - // `response.url()` will be the full URL including the host, so we need to check the pathname - if (new URL(response.url()).pathname === "/rewrite-status-code") { - expect(response.status()).toBe(403); - } + const statusPromise = new Promise((resolve) => { + page.on("response", async (response) => { + // `response.url()` will be the full URL including the host, so we need to check the pathname + if (new URL(response.url()).pathname === "/rewrite-status-code") { + resolve(response.status()); + } + }); }); + await page.goto("/rewrite-status-code"); const el = page.getByText("Rewritten Destination", { exact: true }); await expect(el).toBeVisible(); + expect(statusPromise).resolves.toEqual(403); });