Repository: vercel/next.js
Pull request: Improve tests

- should encode chunk path correctly
    - Run a base version for all bundlers
    - Use `beforePageLoad`
- nonce test:
    - open page once and wait for scripts to load
    - doesn't make sense to retry the whole thing

Closes PACK-5604

Changed files:
filename: test/e2e/app-dir/app/app/script-manual-nonce/show-order.js
patch: @@ -10,7 +10,9 @@ export function ShowScriptOrder() {
       <button
         id="get-order"
         onClick={() => {
-          setOrder(window._script_order)
+          // Copy the array, otherwise React won't rerender after the
+          // `window._script_order.push()` call
+          setOrder([...(window._script_order || [])])
         }}
       >
         get order

filename: test/e2e/app-dir/app/app/script-nonce/show-order.js
patch: @@ -10,7 +10,9 @@ export function ShowScriptOrder() {
       <button
         id="get-order"
         onClick={() => {
-          setOrder(window._script_order)
+          // Copy the array, otherwise React won't rerender after the
+          // `window._script_order.push()` call
+          setOrder([...(window._script_order || [])])
         }}
       >
         get order

filename: test/e2e/app-dir/app/index.test.ts
patch: @@ -13,26 +13,25 @@ import {
 const isPPREnabledByDefault = process.env.__NEXT_EXPERIMENTAL_PPR === 'true'
 
 describe('app dir - basic', () => {
-  const { next, isNextDev, isNextStart, isNextDeploy, isTurbopack } =
-    nextTestSetup({
-      files: __dirname,
-      buildCommand: process.env.NEXT_EXPERIMENTAL_COMPILE
-        ? 'pnpm compile-mode'
-        : undefined,
-      packageJson: {
-        scripts: {
-          'compile-mode': process.env.NEXT_EXPERIMENTAL_COMPILE
-            ? `next build --experimental-build-mode=compile && next build --experimental-build-mode=generate-env`
-            : undefined,
-        },
-      },
-      dependencies: {
-        nanoid: '4.0.1',
-      },
-      env: {
-        NEXT_PUBLIC_TEST_ID: Date.now() + '',
+  const { next, isNextDev, isNextStart, isNextDeploy } = nextTestSetup({
+    files: __dirname,
+    buildCommand: process.env.NEXT_EXPERIMENTAL_COMPILE
+      ? 'pnpm compile-mode'
+      : undefined,
+    packageJson: {
+      scripts: {
+        'compile-mode': process.env.NEXT_EXPERIMENTAL_COMPILE
+          ? `next build --experimental-build-mode=compile && next build --experimental-build-mode=generate-env`
+          : undefined,
       },
-    })
+    },
+    dependencies: {
+      nanoid: '4.0.1',
+    },
+    env: {
+      NEXT_PUBLIC_TEST_ID: Date.now() + '',
+    },
+  })
 
   if (isNextStart) {
     it('should have correct cache-control for SSR routes', async () => {
@@ -169,32 +168,32 @@ describe('app dir - basic', () => {
     })
   }
 
-  // Turbopack has different chunking in dev/production which results in the entrypoint name not being included in the outputs.
-  if (!process.env.IS_TURBOPACK_TEST) {
-    it('should encode chunk path correctly', async () => {
-      await next.fetch('/dynamic-client/first/second')
-      const browser = await next.browser('/')
-      const requests = []
-      browser.on('request', (req) => {
-        requests.push(req.url())
-      })
+  it('should encode chunk path correctly', async () => {
+    const requests = []
+    const browser = await next.browser('/dynamic-client/first/second', {
+      beforePageLoad(page) {
+        page.on('request', (req) => {
+          requests.push(req.url())
+        })
+      },
+    })
 
-      await browser.eval(
-        'window.location.href = "/dynamic-client/first/second"'
-      )
+    await browser.waitForElementByCss('#id-page-params')
 
-      await browser.waitForElementByCss('#id-page-params')
+    expect(requests).not.toEqual(
+      expect.arrayContaining([expect.stringContaining('[category]')])
+    )
 
-      expect(
-        requests.some(
-          (req) =>
-            req.includes(
-              encodeURI(isTurbopack ? '[category]_[id]' : '/[category]/[id]')
-            ) && req.includes('.js')
-        )
-      ).toBe(true)
-    })
-  }
+    // Turbopack doesn't recreate the original folder structure for the output chunks
+    if (!process.env.IS_TURBOPACK_TEST) {
+      expect(requests).toEqual(
+        // e.g. _next/static/chunks/app/dynamic-client/%5Bcategory%5D/%5Bid%5D/page-6e188d657a208f8e.js?dpl=...
+        expect.arrayContaining([
+          expect.stringMatching(/.*%5Bcategory%5D\/%5Bid%5D.*\.js/),
+        ])
+      )
+    }
+  })
 
   it.each([
     { pathname: '/redirect-1' },
@@ -393,7 +392,7 @@ describe('app dir - basic', () => {
     it('should serve polyfills for browsers that do not support modules', async () => {
       const html = await next.render('/dashboard/index')
       expect(html).toMatch(
-        isTurbopack
+        process.env.IS_TURBOPACK_TEST
           ? /<script src="\/_next\/static\/chunks\/([\w-]*polyfill-nomodule|[0-9a-f]+)\.js" noModule="">/
           : /<script src="\/_next\/static\/chunks\/polyfills(-\w+)?\.js" noModule="">/
       )
@@ -1721,12 +1720,12 @@ describe('app dir - basic', () => {
       })
 
       if (!isNextDev) {
+        // Fails in dev due to CSP header
         const browser = await next.browser('/script-nonce')
-
         await retry(async () => {
           await browser.elementByCss('#get-order').click()
           const order = JSON.parse(await browser.elementByCss('#order').text())
-          expect(order?.length).toBe(2)
+          expect(order).toEqual([2, 1])
         })
       }
     })
@@ -1746,15 +1745,12 @@ describe('app dir - basic', () => {
         expect(element.attribs.nonce).toBeTruthy()
       })
 
-      if (!isNextDev) {
-        const browser = await next.browser('/script-manual-nonce')
-
-        await retry(async () => {
-          await browser.elementByCss('#get-order').click()
-          const order = JSON.parse(await browser.elementByCss('#order').text())
-          expect(order?.length).toBe(2)
-        })
-      }
+      const browser = await next.browser('/script-manual-nonce')
+      await retry(async () => {
+        await browser.elementByCss('#get-order').click()
+        const order = JSON.parse(await browser.elementByCss('#order').text())
+        expect(order).toEqual([2, 1])
+      })
     })
 
     it('should pass manual `nonce` pages', async () => {
@@ -1772,14 +1768,12 @@ describe('app dir - basic', () => {
         expect(element.attribs.nonce).toBeTruthy()
       })
 
-      if (!isNextDev) {
-        await retry(async () => {
-          const browser = await next.browser('/pages-script-manual-nonce')
-          await browser.elementByCss('#get-order').click()
-          const order = JSON.parse(await browser.elementByCss('#order').text())
-          expect(order?.length).toBe(2)
-        })
-      }
+      const browser = await next.browser('/pages-script-manual-nonce')
+      await retry(async () => {
+        await browser.elementByCss('#get-order').click()
+        const order = JSON.parse(await browser.elementByCss('#order').text())
+        expect(order).toEqual([2, 1])
+      })
     })
 
     it('should pass nonce when using next/font', async () => {

filename: test/lib/next-modes/next-deploy.ts
patch: @@ -111,6 +111,13 @@ export class NextDeployInstance extends NextInstance {
       )
     }
 
+    if (process.env.IS_TURBOPACK_TEST) {
+      additionalEnv.push(`IS_TURBOPACK_TEST=1`)
+    }
+    if (process.env.IS_WEBPACK_TEST) {
+      additionalEnv.push(`IS_WEBPACK_TEST=1`)
+    }
+
     const deployRes = await execa(
       'vercel',
       [