Files
Jamiboy Mohammad f825d34b75 test: enable verified tooling deploy tests (#98525)
## Summary

Enable the same 26 previously selected deployment-test scopes across 25
tooling test files, now in a stack rooted on canary. Remove 26
`skipDeployment` options and their obsolete skip guards. Other mode,
bundler, middleware, and Cache Components exclusions remain in place.

This preserves the selection with passing evidence from the previous
deployment runs. No additional candidate scopes are enabled; excluded
variants are not counted as deployment coverage.

## Verification

- All selected test registration names and assertion bodies match the
previous enabled revision, checked by AST comparison.
- Verified that the canary diff contains only the inventoried exclusions
and their obsolete skip plumbing; other exclusions are preserved.
- Formatting and lint passed; 77 gate infrastructure unit tests passed.
- Full local bootstrap was blocked by missing package-level dependencies
in the temporary worktree. Fresh deployment execution on these rewritten
commits remains to be verified in CI.

<details>
<summary>Preserved scope inventory (26)</summary>

- ID 146: `test/e2e/app-dir/app-config-crossorigin/index.test.ts` —
`describe('app dir - crossOrigin config', () => {
    const { next } = nextTestSetup({
      files: __dirname,
    })

    it('should render correctly with assetPrefix: "/"', async () => {
      const $ = await next.render$('/')
// Only potential external (assetPrefix) <script /> and <link /> should
have crossorigin attribute
      $(
'script[src*="https://example.vercel.sh"],
link[href*="https://example.vercel.sh"]'
      ).each((_, el) => {
        const crossOrigin = $(el).attr('crossorigin')
        expect(crossOrigin).toBe('use-credentials')
      })

// Inline <script /> (including RSC payload) and <link /> should not
have crossorigin attribute
      $('script:not([src]), link:not([href])').each((_, el) => {
        const crossOrigin = $(el).attr('crossorigin')
        expect(crossOrigin).toBeUndefined()
      })

// Same origin <script /> and <link /> should not have crossorigin
attribute either
      $('script[src^="/"], link[href^="/"]').each((_, el) => {
        const crossOrigin = $(el).attr('crossorigin')
        expect(crossOrigin).toBeUndefined()
      })
    })
  })`
- ID 148:
`test/e2e/app-dir/import-meta-glob-text-type/import-meta-glob-text-type.test.ts`
— `describe('turbopack `text` / `raw` module types', () => {
  const { next } = nextTestSetup({
    files: __dirname,
  })

it('should load matched files as strings through a `?raw` rule', async
() => {
    const $ = await next.render$('/raw')
    const items = $('li')
      .map((_, el) => $(el).text())
      .get()

    expect(items).toEqual([
      './content/delta.txt: delta contents',
      './content/gamma.txt: gamma contents',
    ])
  })

it('should treat `raw` and `text` the same in a `?raw` rule', async ()
=> {
    const $ = await next.render$('/raw-alias')
    const items = $('li')
      .map((_, el) => $(el).text())
      .get()

    expect(items).toEqual([
      './content/delta.rst: delta contents',
      './content/gamma.rst: gamma contents',
    ])
  })

it('should treat `raw` and `text` the same for a plain import', async ()
=> {
    const $ = await next.render$('/alias')

expect(JSON.parse($('#raw').text())).toBe('# alpha\n\nsome markdown\n')
    expect($('#equal').text()).toBe('true')
  })
})`
- ID 153:
`test/e2e/app-dir/multiple-lockfiles/multiple-lockfiles-with-output-file-tracing-root.test.ts`
— `describe('multiple-lockfiles - has-output-file-tracing-root', () => {
  const { next } = nextTestSetup({
    files: {
      app: new FileRef(join(__dirname, 'app')),
      // This will silence the multiple lockfiles warning.
'next.config.js': `module.exports = { outputFileTracingRoot: __dirname
}`,
// Write a package-lock.json file to the parent directory to simulate
      // multiple lockfiles.
      '../package.json': JSON.stringify({
        name: 'parent-workspace',
        version: '1.0.0',
      }),
      '../package-lock.json': JSON.stringify({
        name: 'parent-workspace',
        version: '1.0.0',
        lockfileVersion: 3,
packages: { '': { name: 'parent-workspace', version: '1.0.0' } },
      }),
    },
    // So that ../package-lock.json doesn't leave the isolated testDir
    subDir: 'test',
    // The workspace file would suppress the warning itself, so the test
    // wouldn't be exercising `outputFileTracingRoot`.
    deleteWorkspaceFile: true,
  })

  it('should not have multiple lockfiles warnings', async () => {
    expect(next.cliOutput).not.toMatch(
/We detected multiple lockfiles and selected the directory of .+ as the
root directory\./
    )
  })
})`
- ID 154:
`test/e2e/app-dir/multiple-lockfiles/multiple-lockfiles-with-turbo-root.test.ts`
— `describe('multiple-lockfiles - has-turbo-root', () => {
  const { next } = nextTestSetup({
    files: {
      app: new FileRef(join(__dirname, 'app')),
      // This will silence the multiple lockfiles warning.
'next.config.js': `module.exports = { turbopack: { root: __dirname } }`,
// Write a package-lock.json file to the parent directory to simulate
      // multiple lockfiles.
      '../package.json': JSON.stringify({
        name: 'parent-workspace',
        version: '1.0.0',
      }),
      '../package-lock.json': JSON.stringify({
        name: 'parent-workspace',
        version: '1.0.0',
        lockfileVersion: 3,
packages: { '': { name: 'parent-workspace', version: '1.0.0' } },
      }),
    },
    // So that ../package-lock.json doesn't leave the isolated testDir
    subDir: 'test',
    // The workspace file would suppress the warning itself, so the test
    // wouldn't be exercising `turbopack.root`.
    deleteWorkspaceFile: true,
  })

  it('should not have multiple lockfiles warnings', async () => {
    expect(next.cliOutput).not.toMatch(
/We detected multiple lockfiles and selected the directory of .+ as the
root directory\./
    )
  })
})`
- ID 170: `test/e2e/app-dir/segment-config-ts/segment-config-ts.test.ts`
— `describe('TypeScript type expressions in route segment config', () =>
{
  const { next, isNextStart } = nextTestSetup({
    files: __dirname,
  })

  describe('app directory', () => {
it('should pick up maxDuration declared with `as` type assertion', async
() => {
      const $ = await next.render$('/as')
      expect($('main').text()).toBe('hello')
    })

it('should pick up maxDuration declared with `as const` assertion',
async () => {
      const $ = await next.render$('/as-const')
      expect($('main').text()).toBe('hello')
    })

it('should pick up maxDuration declared with `satisfies`', async () => {
      const $ = await next.render$('/satisfies')
      expect($('main').text()).toBe('hello')
    })
  })

  describe('pages directory', () => {
it('should pick up maxDuration from config object declared with `as`',
async () => {
      const $ = await next.render$('/config-as')
      expect($('main').text()).toBe('hello')
    })

it('should pick up maxDuration from config object declared with `as
const`', async () => {
      const $ = await next.render$('/config-as-const')
      expect($('main').text()).toBe('hello')
    })

it('should pick up maxDuration from config object declared with
`satisfies`', async () => {
      const $ = await next.render$('/config-satisfies')
      expect($('main').text()).toBe('hello')
    })
  })

  if (isNextStart) {
    it('should parse the config correctly', async () => {
      const config = await next.readJSON(
        '.next/server/functions-config-manifest.json'
      )
      expect(config).toMatchInlineSnapshot(`
       {
         "functions": {
           "/as": {
             "maxDuration": 1000,
           },
           "/as-const": {
             "maxDuration": 1000,
           },
           "/config-as": {
             "maxDuration": 1000,
           },
           "/config-as-const": {
             "maxDuration": 1000,
           },
           "/config-satisfies": {
             "maxDuration": 1000,
           },
           "/satisfies": {
             "maxDuration": 1000,
           },
         },
         "version": 1,
       }
      `)
    })
  }
})`
- ID 172: `test/e2e/app-dir/trace-build-file/trace-build-file.test.ts` —
`describe('trace-build-file', () => {
  const { next } = nextTestSetup({
    files: __dirname,
    skipStart: !isNextDev,
    env: {
// Enable persistent caching even when the git working directory is
      // dirty (e.g. when developing Next.js itself). Without this, the
      // cache falls back to a temp directory and persistence/compaction
      // spans are not emitted.
      TURBO_ENGINE_IGNORE_DIRTY: '1',
    },
  })

  if (isNextStart) {
it('should create .next/trace-build file during production build', async
() => {
      // Build the app to trigger trace generation
      await next.build()

      // Check that trace-build file exists
      const traceBuildPath = join(next.testDir, '.next/trace-build')
      expect(existsSync(traceBuildPath)).toBe(true)
    })

    it('should contain high-level build trace events', async () => {
      // Ensure we have a fresh build
      await next.build()

      const traceBuildPath = join(next.testDir, '.next/trace-build')
      expect(existsSync(traceBuildPath)).toBe(true)

      const traceStructure = parseTraceFile(traceBuildPath)

      // Should have events
      expect(traceStructure.events.length).toBeGreaterThan(0)

      // Should contain the main next-build event
const nextBuildEvents = traceStructure.eventsByName.get('next-build')
      expect(nextBuildEvents).toBeDefined()
      expect(nextBuildEvents.length).toBe(1)

      const nextBuildEvent = nextBuildEvents[0]
      expect(nextBuildEvent).toHaveProperty('name', 'next-build')
      expect(nextBuildEvent).toHaveProperty('traceId')
      expect(nextBuildEvent).toHaveProperty('id')
      expect(nextBuildEvent).toHaveProperty('duration')
      expect(typeof nextBuildEvent.duration).toBe('number')
      expect(typeof nextBuildEvent.traceId).toBe('string')
      expect(typeof nextBuildEvent.id).toBe('number')
    })

    it('should only contain allowlisted events', async () => {
      await next.build()

      const traceBuildPath = join(next.testDir, '.next/trace-build')
      const traceStructure = parseTraceFile(traceBuildPath)

      // const allowlistedEvents = new Set([
      //   'next-build',
      //   'run-turbopack',
      //   'run-webpack',
      //   'run-typescript',
      //   'run-eslint',
      //   'static-check',
      //   'static-generation',
      //   'output-export-full-static-export',
      // ])

      const foundEvents = new Set<string>()

      for (const event of traceStructure.events) {
        foundEvents.add(event.name)
      }

      if (process.env.IS_TURBOPACK_TEST) {
// Compaction only runs when it is due, so it may or may not appear.
        foundEvents.delete('turbopack-compaction')

        expect([...foundEvents].sort()).toMatchInlineSnapshot(`
                [
                  "next-build",
                  "run-turbopack",
                  "run-typescript",
                  "static-check",
                  "static-generation",
                  "telemetry-flush",
                  "turbopack-persistence",
                ]
              `)
      } else {
        expect([...foundEvents].sort()).toMatchInlineSnapshot(`
         [
           "collect-build-traces",
           "next-build",
           "run-typescript",
           "run-webpack",
           "static-check",
           "static-generation",
           "telemetry-flush",
         ]
        `)
      }
    })

it('should have next-build as root span with proper hierarchy', async ()
=> {
      await next.build()

      const traceBuildPath = join(next.testDir, '.next/trace-build')
      const traceStructure = parseTraceFile(traceBuildPath)

// Should have no orphaned events (all events should have valid parent
references)
      expect(traceStructure.orphanedEvents).toHaveLength(0)

      // Should have at one root event
      expect(traceStructure.rootEvents.length).toBe(1)

      // next-build should be the main root event
const nextBuildEvents = traceStructure.eventsByName.get('next-build')
      expect(nextBuildEvents).toBeDefined()
      expect(nextBuildEvents.length).toBe(1)

      const nextBuildEvent = nextBuildEvents[0]
      expect(nextBuildEvent.parentId).toBeUndefined() // Should be root
      expect(traceStructure.rootEvents).toContain(nextBuildEvent)

// Other build events should be children of next-build or have valid
parent references
const buildEvents = ['run-webpack', 'run-typescript', 'run-eslint']
      for (const eventName of buildEvents) {
        const events = traceStructure.eventsByName.get(eventName)
        if (events && events.length > 0) {
          for (const event of events) {
            if (event.parentId) {
              // Should have a valid parent
              expect(
                traceStructure.eventsById.has(event.parentId.toString())
              ).toBe(true)
              const parent = traceStructure.eventsById.get(
                event.parentId.toString()
              )

// Parent should either be next-build or another valid event
              expect(parent).toBeDefined()
              expect(parent.traceId).toBe(event.traceId) // Same trace
            }
          }
        }
      }
    })

    it('should have consistent traceId across all events', async () => {
      await next.build()

      const traceBuildPath = join(next.testDir, '.next/trace-build')
      const traceStructure = parseTraceFile(traceBuildPath)

      expect(traceStructure.events.length).toBeGreaterThan(0)

      const firstEvent = traceStructure.events[0]
      expect(firstEvent.traceId).toBeDefined()
      expect(typeof firstEvent.traceId).toBe('string')
      expect(firstEvent.traceId.length).toBeGreaterThan(0)

      // All events should have the same traceId
      for (const event of traceStructure.events) {
        expect(event.traceId).toBe(firstEvent.traceId)
      }
    })
  }

  if (isNextDev) {
it('should not create trace-build file in development mode', async () =>
{
      // Make a request to trigger some activity
      await next.render('/')

      // Check that trace-build file does not exist
      const traceBuildPath = join(next.testDir, '.next/trace-build')
      expect(existsSync(traceBuildPath)).toBe(false)
    })
  }

  it('should work with basic page rendering', async () => {
    if (isNextStart) {
      await next.start()
    }
    const $ = await next.render$('/')
    expect($('p').text()).toBe('hello world')
  })
})`
- ID 173:
`test/e2e/app-dir/turbopack-loader-content-type/turbopack-loader-content-type.test.ts`
— `describe('turbopack-loader-content-type', () => {
  const { next } = nextTestSetup({
    files: __dirname,
  })

it('should apply loader based on contentType glob pattern', async () =>
{
    const $ = await next.render$('/')
    const text = $('#text').text()
    expect(text).toBe('TEXT:Hello World')
  })

it('should apply loader based on contentType for text/javascript', async
() => {
    const $ = await next.render$('/')
    const text = $('#js').text()
    expect(text).toBe('Hello from loader')
  })

  it('should apply loader based on contentType regex', async () => {
    const $ = await next.render$('/')
    const text = $('#image').text()
    expect(text).toMatch(/^IMAGE:\d+ bytes$/)
  })
})`
- ID 181:
`test/e2e/app-dir/webpack-loader-conditions/webpack-loader-conditions.test.ts`
— `describe('webpack-loader-conditions', () => {
  const { next } = nextTestSetup({
    files: __dirname,
  })

  it('should render correctly on server site', async () => {
    const res = await next.fetch('/')
    const html = (await res.text()).replaceAll(/<!-- -->/g, '')
    expect(html).toContain(`server: {&quot;default&quot;:true}`)
    expect(html).toContain(`client: {&quot;default&quot;:true}`)
    expect(html).toContain(`foreignClient: {}`)
  })

  it('should render correctly on client side', async () => {
    const browser = await next.browser('/')
    const text = await browser.elementByCss('body').text()
expect(text).toContain(`server: ${JSON.stringify({ default: true })}`)
expect(text).toContain(`client: ${JSON.stringify({ browser: true })}`)
    expect(text).toContain(
`foreignClient: ${JSON.stringify({ browser: true, foreign: true })}`
    )
  })
})`
- ID 183: `test/e2e/app-dir/webpack-loader-fs/webpack-loader-fs.test.ts`
— `describe('webpack-loader-fs', () => {
  const { next } = nextTestSetup({
    files: __dirname,
  })

  it('should allow reading the input FS', async () => {
    const $ = await next.render$('/')
    expect($('#test').text()).toBe(
"Buffer read: 18, string read: 'this is some data', binary read: 6765,
glob read: 'one.txt'"
    )
  })
})`
- ID 184:
`test/e2e/app-dir/webpack-loader-import-module/webpack-loader-import-module.test.ts`
— `describe('webpack-loader-import-module', () => {
  const { next, isTurbopack } = nextTestSetup({
    files: __dirname,
  })

it('should support this.importModule() in a webpack loader', async () =>
{
    const $ = await next.render$('/')
    expect($('#title').text()).toBe('Import Module Works')
    expect($('#items').text()).toBe('apple, banana, cherry')
    // CJS dependency that itself requires a JSON file
    expect($('#cjs-greeting').text()).toBe('hello from cjs')
    expect($('#version').text()).toBe('1.0.0')
    // ESM dependency imported from config-data.ts
    expect($('#esm-label').text()).toBe('hello from esm')
    // ESM .mjs module (config-data.mjs)
    expect($('#mjs-title').text()).toBe('ESM Config Works')
    expect($('#mjs-esm-label').text()).toBe('hello from esm')

    // resolveAlias: importModule with alias as request
    expect($('#alias-value').text()).toBe('resolved via alias')
    // resolveAlias: dependency of importModule target uses alias
    expect($('#alias-dep-label').text()).toBe('hello from esm')
    // loader rules: importModule on file requiring custom loader
expect($('#custom-data-value').text()).toBe('hello from custom loader')
// loader rules: dependency of importModule target needs custom loader
    expect($('#consumed-value').text()).toBe('hello from custom loader')

    if (isTurbopack) {
      // new URL('./image.png', import.meta.url) in url-wasm-data.ts
      expect($('#image-url').text()).toContain('image')
      expect($('#image-url').text()).toMatch(/\.png/)
      // WebAssembly add(1, 2) from add.wasm in url-wasm-data.ts
      expect($('#wasm-add-result').text()).toBe('3')
      // Dynamic import('./module.js') in url-wasm-data.ts
      expect($('#dynamic-value').text()).toBe('loaded dynamically')
      // new URL('./image.png', import.meta.url) in url-wasm-data.mjs
      expect($('#mjs-image-url').text()).toContain('image')
      expect($('#mjs-image-url').text()).toMatch(/\.png/)
      // WebAssembly add(10, 20) from add.wasm in url-wasm-data.mjs
      expect($('#mjs-wasm-add-result').text()).toBe('30')
      // Dynamic import('./module.js') in url-wasm-data.mjs
      expect($('#mjs-dynamic-value').text()).toBe('loaded dynamically')
    }
  })
})`
- ID 185:
`test/e2e/app-dir/webpack-loader-module-type/webpack-loader-module-type.test.ts`
— `describe('webpack-loader-module-type', () => {
  const { next, isTurbopack } = nextTestSetup({
    files: __dirname,
  })

// bytes type is Turbopack-only, webpack doesn't have a direct
equivalent
  const itTurbopackOnly = isTurbopack ? it : it.skip

  it('should load svg as asset/resource and return URL', async () => {
    const $ = await next.render$('/')
    const src = $('#svg-url').text()
    // asset/resource should emit the file and return URL path
    expect(src).toMatch(
      /\/_next\/static\/(immutable\/)?media\/test\.[0-9a-z_-]+\.svg$/
    )
  })

  itTurbopackOnly(
    'should load data file as bytes and return Uint8Array',
    async () => {
      const $ = await next.render$('/')
      const bytesType = $('#bytes-type').text()
      const bytesLength = $('#bytes-length').text()
      const bytesText = $('#bytes-text').text()

      // eslint-disable-next-line jest/no-standalone-expect
      expect(bytesType).toBe('Uint8Array')
      // eslint-disable-next-line jest/no-standalone-expect
      expect(bytesLength).toBe('11')
      // eslint-disable-next-line jest/no-standalone-expect
      expect(bytesText).toBe('hello world')
    }
  )
})`
- ID 186:
`test/e2e/app-dir/webpack-loader-resolve/webpack-loader-resolve.test.ts`
— `describe('webpack-loader-resolve', () => {
  const { next } = nextTestSetup({
    files: __dirname,
  })

it('should support resolving absolute path via loader getResolve', async
() => {
    const $ = await next.render$('/')
    expect($('#absolute').text()).toBe('abc')
    expect($('#relative').text()).toBe('xyz')
  })

  it('should support loader getResolve without options', async () => {
    const $ = await next.render$('/no-options')
    expect($('#no-options').text()).toBe('xyz')
  })

  it('should support callback-style loader resolve', async () => {
    const $ = await next.render$('/callback')
    expect($('#resolved').text()).toBe('resolved-value.js')
  })
})`
- ID 187:
`test/e2e/app-dir/webpack-loader-resource-query/webpack-loader-resource-query.test.js`
— `describe('webpack-loader-resource-query', () => {
  const { next } = nextTestSetup({
    files: __dirname,
  })

  it('should pass query to loader', async () => {
    await next.render$('/')

    expect(next.cliOutput).toContain('resource query:  ?test=hi')
  })

  it('should apply loader based on resourceQuery', async () => {
    const $ = await next.render$('/')
    const text = $('#reversed').text()
    expect(text).toBe('dlroW olleH')
  })

  it('should apply loader based on resourceQuery regex', async () => {
    const $ = await next.render$('/')
    const text = $('#upper').text()
    expect(text).toBe('HELLO WORLD')
  })
})`
- ID 188:
`test/e2e/app-dir/webpack-loader-ts-transform/webpack-loader-ts-transform.test.ts`
— `describe('webpack-loader-ts-transform', () => {
  const { next } = nextTestSetup({
    files: __dirname,
  })

it('should accept Typescript returned from Webpack loaders', async () =>
{
    const $ = await next.render$('/')
    expect($('p').text()).toBe('something')
  })
})`
- ID 189: `test/e2e/app-dir/with-babel/with-babel.test.ts` —
`describe('with babel', () => {
  const { next, isNextStart, isTurbopack } = nextTestSetup({
    files: __dirname,
  })

  it('should support babel in app dir', async () => {
    const $ = await next.render$('/')
    expect($('h1').text()).toBe('hello')
  })

  if (isNextStart) {
// Turbopack always runs SWC, so this shouldn't be an issue, but this
test
    // refers to a webpack-specific output path.
    // https://github.com/vercel/next.js/pull/51067
    ;(isTurbopack ? it.skip : it)(
      'should contain og package files in middleware',
      async () => {
        await retry(async () => {
const middleware = await next.readFile('.next/server/middleware.js')
          // @vercel/og default font should be bundled
          expect(middleware).not.toContain('Geist-Regular.ttf')
        })
      }
    )
  }
})`
- ID 192: `test/e2e/config-schema-check/index.test.ts` —
`describe('next.config.js schema validating - defaultConfig', () => {
  const { next } = nextTestSetup({
    files: {
      'pages/index.js': `
    export default function Page() {
      return <p>hello world</p>
    }
    `,
      'next.config.js': `
    module.exports = (phase, { defaultConfig }) => {
      return defaultConfig
    }
    `,
    },
  })

  it('should validate against defaultConfig', async () => {
    const output = stripAnsi(next.cliOutput)

expect(output).not.toContain('Invalid next.config.js options detected')
  })
})`
- ID 193: `test/e2e/config-schema-check/index.test.ts` —
`describe('next.config.js schema validating - invalid config', () => {
  const { next, isNextStart } = nextTestSetup({
    files: {
      'pages/index.js': `
    export default function Page() {
      return <p>hello world</p>
    }
    `,
      'next.config.js': `
    module.exports = {
      badKey: 'badValue'
    }
    `,
    },
  })

  it('should warn the invalid next config', async () => {
    await check(() => {
      const output = stripAnsi(next.cliOutput)
      const warningTimes = output.split('badKey').length - 1

expect(output).toContain('Invalid next.config.js options detected')
      expect(output).toContain('badKey')
      // for next start and next build we both display the warnings
      expect(warningTimes).toBe(isNextStart ? 2 : 1)

      return 'success'
    }, 'success')
  })
})`
- ID 198: `test/e2e/import-meta-env/import-meta-env.test.ts` —
`describe('import.meta.env', () => {
  const { next } = nextTestSetup({
    files: __dirname,
  })

it('exposes built-in environment values on the server and client', async
() => {
    const browser = await next.browser('/docs')
    const expectedMode = isNextDev ? 'development' : 'production'

    expect(
      JSON.parse(await browser.elementByCss('#server-env dd').text())
    ).toEqual({
      DEV: isNextDev,
      PROD: !isNextDev,
      MODE: expectedMode,
      BASE_URL: '/docs/',
      SSR: true,
    })
    expect(
      JSON.parse(await browser.elementByCss('#client-env dd').text())
    ).toEqual({
      DEV: isNextDev,
      PROD: !isNextDev,
      MODE: expectedMode,
      BASE_URL: '/docs/',
      SSR: false,
    })
  })

it('supports static bracket access and unknown properties', async () =>
{
    const browser = await next.browser('/docs')
    const $ = await next.render$('/docs')
    const expectedMode = isNextDev ? 'development' : 'production'

    expect($('#server-env dd').eq(1).text()).toBe(expectedMode)
    expect($('#server-env dd').eq(2).text()).toBe('undefined')
    expect(
      await browser.elementByCss('#client-env dd:nth-of-type(2)').text()
    ).toBe(expectedMode)
    expect(
      await browser.elementByCss('#client-env dd:nth-of-type(3)').text()
    ).toBe('undefined')
  })
})`
- ID 199: `test/e2e/import-meta-glob/import-meta-glob.test.ts` —
`describe('import-meta-glob', () => {
  const { next } = nextTestSetup({
    files: __dirname,
  })

  it('should resolve lazy glob modules', async () => {
    const $ = await next.render$('/')
    const lazyKeys = JSON.parse($('#lazy-keys').text())
    expect(lazyKeys).toEqual([
      './modules/bar.ts',
      './modules/foo.ts',
      './modules/skip.ts',
    ])

    const lazyResults = JSON.parse($('#lazy-results').text())
    expect(lazyResults).toEqual({
      './modules/bar.ts': 'bar',
      './modules/foo.ts': 'foo',
      './modules/skip.ts': 'skip',
    })
  })

  it('should resolve eager glob modules', async () => {
    const $ = await next.render$('/')
    const eagerKeys = JSON.parse($('#eager-keys').text())
    expect(eagerKeys).toEqual([
      './modules/bar.ts',
      './modules/foo.ts',
      './modules/skip.ts',
    ])

    const eagerResults = JSON.parse($('#eager-results').text())
    expect(eagerResults).toEqual({
      './modules/bar.ts': 'bar',
      './modules/foo.ts': 'foo',
      './modules/skip.ts': 'skip',
    })
  })

  it('should resolve named import glob modules', async () => {
    const $ = await next.render$('/')
    const defaultResults = JSON.parse($('#default-results').text())
    expect(defaultResults).toEqual({
      './modules/bar.ts': 'bar-value',
      './modules/foo.ts': 'foo-value',
      './modules/skip.ts': 'skip-value',
    })
  })

  it('should support negative patterns', async () => {
    const $ = await next.render$('/')
    const filteredKeys = JSON.parse($('#filtered-keys').text())
expect(filteredKeys).toEqual(['./modules/bar.ts', './modules/foo.ts'])

    const filteredResults = JSON.parse($('#filtered-results').text())
    expect(filteredResults).toEqual({
      './modules/bar.ts': 'bar',
      './modules/foo.ts': 'foo',
    })
  })

  it('should support multiple patterns', async () => {
    const $ = await next.render$('/')
    const multiKeys = JSON.parse($('#multi-keys').text())
    expect(multiKeys).toEqual([
      './modules/bar.ts',
      './modules/foo.ts',
      './modules/skip.ts',
      './other/baz.ts',
    ])

    const multiResults = JSON.parse($('#multi-results').text())
    expect(multiResults).toEqual({
      './modules/bar.ts': 'bar',
      './modules/foo.ts': 'foo',
      './modules/skip.ts': 'skip',
      './other/baz.ts': 'baz',
    })
  })
})`
- ID 200: `test/e2e/jsconfig-baseurl/jsconfig-baseurl.test.ts` —
`describe('jsconfig.json baseurl', () => {
  const { next } = nextTestSetup({
    files: __dirname,
  })

  describe('default behavior', () => {
    it('should render the page', async () => {
      const $ = await next.render$('/hello')
      expect($('body').text()).toMatch(/World/)
    })

// Integration ran this under `launchApp` only. e2e splits dev vs `next
start` jobs, so
// `it.skip` when !isNextDev is correct: the module-not-found overlay is
dev-only; production
// jobs still cover `should trace correctly` under `should build` below.
    ;(isNextDev ? it : it.skip)(
      'should have correct module not found error',
      async () => {
        const contents = await next.readFile('pages/hello.js')
        try {
          await next.patchFile(
            'pages/hello.js',
            contents.replace('components/world', 'components/worldd')
          )

          await retry(async () => {
            await next.render('/hello').catch(() => {})
            const strippedOutput = stripAnsi(next.cliOutput)
            expect(strippedOutput).toMatch(
              /Module not found: Can't resolve 'components\/worldd'/
            )
          })
        } finally {
          await next.patchFile('pages/hello.js', contents)
        }
      }
    )
  })
  ;(isNextStart ? describe : describe.skip)('should build', () => {
    it('should trace correctly', async () => {
      const helloTrace = JSON.parse(
        await next.readFile('.next/server/pages/hello.js.nft.json')
      )
      expect(
        helloTrace.files.some((file: string) =>
          file.includes('components/world.js')
        )
      ).toBe(false)
      expect(
helloTrace.files.some((file: string) => file.includes('react/index.js'))
      ).toBe(true)
    })
  })
})`
- ID 207: `test/e2e/swc-plugins-env/index.test.ts` —
`describe('swc-plugins-env', () => {
  const { next, isNextDev } = nextTestSetup({
    files: __dirname,
  })

  it('should pass correct environment to swc plugins', async () => {
    const $ = await next.render$('/')
    if (isNextDev) {
expect($('main').text()).toBe('The SWC plugin received env=development')
    } else {
expect($('main').text()).toBe('The SWC plugin received env=production')
    }
  })
})`
- ID 208: `test/e2e/swc-plugins/index.test.ts` — `describe('supports
swcPlugins', () => {
    const { next } = nextTestSetup({
      files: __dirname,
      dependencies: {
        '@swc/plugin-react-remove-properties': '13.0.0',
      },
    })

    it('basic case', async () => {
      const html = await next.render('/')
      expect(html).toContain('Hello World')
      expect(html).not.toContain('data-custom-attribute')
    })
  })`
- ID 212: `test/e2e/transpile-packages-typescript-foreign/index.test.ts`
— `describe('with transpilePackages', () => {
    const { next } = nextTestSetup({
      files: __dirname,
      dependencies: {
        pkg: `file:./pkg`,
      },
      nextConfig: {
        transpilePackages: ['pkg'],
      },
    })

    it('should work', async () => {
      const $ = await next.render$('/')
      expect($('main').text()).toEqual('Hello 123')
    })
  })`
- ID 213: `test/e2e/turbopack-import-with-type/index.test.ts` —
`describe('turbopack-import-with-type', () => {
  const { next } = nextTestSetup({
    files: __dirname,
  })

// Testing this together on one route ensures we also avoid weird
duplicate module ident things
it('supports import with type: text, type: bytes, and type: json', async
() => {
    const response = JSON.parse(await next.render('/api'))
    expect(response).toEqual({
      text: {
        typeofString: true,
        length: 12,
        content: 'hello world\n',
      },
      jsAsText: {
        typeofString: true,
        content: jsContent,
      },
      bytes: {
        instanceofUint8Array: true,
        length: 18,
        content: 'this is some data\n',
      },
      jsAsBytes: {
        instanceofUint8Array: true,
        content: jsContent,
      },
      configuredAsJsAsBytes: {
        instanceofUint8Array: true,
        content:
"throw new Error('this file is configured as ecmascript but imported as
bytes')\n",
      },
      json: {
        typeofObject: true,
        content: { hello: 'world' },
      },
      jsonAsText: {
        typeofString: true,
        content: '{ "hello": "world" }\n',
      },
    })
  })
})`
- ID 214: `test/e2e/turbopack-loader-config/index.test.ts` —
`describe('turbopack-loader-config', () => {
  const { next, isTurbopack, isNextDev } = nextTestSetup({
    files: __dirname,
// we can't set `nextConfig` inline because it contains regexes that
fail to serialize, it needs
    // to be set in a separate module (`next.config.ts`)
  })

  if (!isTurbopack) {
    it('should only run the test in turbopack', () => {})
    return
  }

it('should replace modules with their loader-generated versions', async
() => {
    const response = JSON.parse(await next.render('/api'))
    expect(response).toEqual({
      foo: 'default return value',
bar: 'has export substring' + (isNextDev ? ' on dev' : ' on prod'),
    })
  })
})`
- ID 217: `test/e2e/typescript/typescript.test.ts` —
`describe('TypeScript Features', () => {
  const { next, isTurbopack } = nextTestSetup({
    files: __dirname,
    dependencies: {
      sass: 'latest',
    },
  })

  it('should render the page', async () => {
    const $ = await next.render$('/hello')
    expect($('body').text()).toMatch(/Hello World/)
    expect($('body').text()).toMatch(/1000000000000/)
  })

  it('should render the cookies page', async () => {
    const $ = await next.render$('/ssr/cookies')
    expect($('#cookies').text()).toBe('{}')
  })

  it('should render the cookies page with cookies', async () => {
    const res = await next.fetch('/ssr/cookies', {
      headers: {
        Cookie: 'key=value;',
      },
    })
    const html = await res.text()
    expect(html).toContain(`{"key":"value"}`)
  })

  it('should render the generics page', async () => {
    const $ = await next.render$('/generics')
    expect($('#value').text()).toBe('Hello World from Generic')
  })

it('should render the angle bracket type assertions page', async () => {
    const $ = await next.render$('/angle-bracket-type-assertions')
    expect($('#value').text()).toBe('test')
  })

// Turbopack prefers `.ts`/`.tsx` over `.js`/`.jsx`, webpack prefers
`.js`/`.jsx`
  ;(isTurbopack ? it.skip : it)(
    'should resolve files in correct order',
    async () => {
      const $ = await next.render$('/hello')
      // eslint-disable-next-line jest/no-standalone-expect
      expect($('#imported-value').text()).toBe('OK')
    }
  )

  // old behavior:
  it.skip('should report type checking to stdout', () => {
    expect(next.cliOutput).toContain('waiting for typecheck results...')
  })

  it('should respond to sync API route correctly', async () => {
    const html = await next.render('/api/sync')
    const data = JSON.parse(html)
    expect(data).toEqual({ code: 'ok' })
  })

  it('should respond to async API route correctly', async () => {
    const html = await next.render('/api/async')
    const data = JSON.parse(html)
    expect(data).toEqual({ code: 'ok' })
  })

  if (isNextDev) {
it('should not fail to render when an inactive page has an error', async
() => {
      await next.patchFile(
        'pages/evil.tsx',
        `import React from 'react'

export default function EvilPage(): JSX.Element {
  return <div notARealProp />
}
`
      )
      try {
        const $ = await next.render$('/hello')
        expect($('body').text()).toMatch(/Hello World/)
      } finally {
        await next.deleteFile('pages/evil.tsx')
      }
    })
  }

  if (isNextStart) {
    it('should build the app successfully', async () => {
      expect(next.cliOutput).toMatch(/Compiled successfully/)
    })

    it('should not inform when using default tsconfig path', () => {
      expect(next.cliOutput).not.toMatch(/Using tsconfig file:/)
    })
  }
})`

</details>

<details>
<summary>Deployment evidence for the additional scopes</summary>

- `test/e2e/app-dir/app-config-crossorigin/index.test.ts` —
`describe('app dir - crossOrigin config', () => {`:
[normal](https://github.com/vercel/next.js/actions/runs/34426785087/job/102715742650),
[cache](https://github.com/vercel/next.js/actions/runs/34426785087/job/102715742724).
-
`test/e2e/app-dir/webpack-loader-module-type/webpack-loader-module-type.test.ts`
— `describe('webpack-loader-module-type', () => {`:
[normal](https://github.com/vercel/next.js/actions/runs/34426785087/job/102715742634),
[cache](https://github.com/vercel/next.js/actions/runs/34426785087/job/102715742671).
- `test/e2e/app-dir/with-babel/with-babel.test.ts` — `describe('with
babel', () => {`:
[normal](https://github.com/vercel/next.js/actions/runs/34426785087/job/102715742666),
[cache](https://github.com/vercel/next.js/actions/runs/34426785087/job/102715742685).
- `test/e2e/jsconfig-baseurl/jsconfig-baseurl.test.ts` —
`describe('jsconfig.json baseurl', () => {`:
[normal](https://github.com/vercel/next.js/actions/runs/34426785087/job/102715742650),
[cache](https://github.com/vercel/next.js/actions/runs/34426785087/job/102715742724).
- `test/e2e/swc-plugins/index.test.ts` — `describe('supports
swcPlugins', () => {`:
[normal](https://github.com/vercel/next.js/actions/runs/34426785087/job/102715742599),
[cache](https://github.com/vercel/next.js/actions/runs/34426785087/job/102715742667).
- `test/e2e/transpile-packages-typescript-foreign/index.test.ts` —
`describe('with transpilePackages', () => {`:
[normal](https://github.com/vercel/next.js/actions/runs/34426785087/job/102715742666),
[cache](https://github.com/vercel/next.js/actions/runs/34426785087/job/102715742685).
- `test/e2e/typescript/typescript.test.ts` — `describe('TypeScript
Features', () => {`:
[normal](https://github.com/vercel/next.js/actions/runs/34426785087/job/102715742666),
[cache](https://github.com/vercel/next.js/actions/runs/34426785087/job/102715742685).

</details>

<!-- NEXT_JS_LLM -->
2026-09-15 10:29:06 -07:00
..
2026-09-02 16:09:18 +02:00