Files
Jamiboy Mohammad 2ad16804ac test: enable verified assets deploy tests (#98527)
## Summary

Enable the same 11 previously selected deployment-test scopes across 11
assets test files, now in a stack rooted on canary. Remove 11
`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 (11)</summary>

- ID 286: `test/e2e/app-dir/app-css-pageextensions/index.test.ts` —
`describe('app dir - css with pageextensions', () => {
  const { next } = nextTestSetup({
    files: __dirname,
    dependencies: {
      '@picocss/pico': '1.5.7',
      sass: 'latest',
    },
  })

  describe('css support with pageextensions', () => {
describe('page in app directory with pageextention, css should work', ()
=> {
      it('should support global css inside layout', async () => {
        const browser = await next.browser('/css-pageextensions')
        expect(
          await browser.eval(
`window.getComputedStyle(document.querySelector('h1')).color`
          )
        ).toBe('rgb(255, 0, 0)')
      })
    })
  })
})`
- ID 292: `test/e2e/app-dir/dynamic-css/index.test.ts` — `describe('app
dir - dynamic css', () => {
  const { next } = nextTestSetup({
    files: __dirname,
  })

it('should preload all chunks of dynamic component during SSR', async ()
=> {
    const $ = await next.render$('/ssr')
const cssLinks = $('link[rel="stylesheet"][data-precedence="dynamic"]')
    expect(cssLinks.attr('href')).toContain('.css')

    const preloadJsChunks = $('link[rel="preload"]')
    expect(preloadJsChunks.attr('as')).toBe('script')
    expect(preloadJsChunks.attr('fetchpriority')).toContain(`low`)
  })

it('should only apply corresponding css for page loaded that /ssr',
async () => {
    const browser = await next.browser('/ssr')
    await retry(async () => {
      expect(
        await browser.eval(
`window.getComputedStyle(document.querySelector('.text')).color`
        )
      ).toBe('rgb(255, 0, 0)')
// Default border width, which is not effected by bar.css that is not
loaded in /ssr
      expect(
        await browser.eval(
`window.getComputedStyle(document.querySelector('.text')).borderWidth`
        )
      ).toBe('0px')
    })
  })

it('should only apply corresponding css for page loaded in edge
runtime', async () => {
    const browser = await next.browser('/ssr/edge')
    await retry(async () => {
      expect(
        await browser.eval(
`window.getComputedStyle(document.querySelector('.text')).color`
        )
      ).toBe('rgb(255, 0, 0)')
// Default border width, which is not effected by bar.css that is not
loaded in /ssr
      expect(
        await browser.eval(
`window.getComputedStyle(document.querySelector('.text')).borderWidth`
        )
      ).toBe('0px')
    })
  })

it('should only apply corresponding css for page loaded that /another',
async () => {
    const browser = await next.browser('/another')
    await retry(async () => {
      expect(
        await browser.eval(
`window.getComputedStyle(document.querySelector('.text')).color`
        )
      ).not.toBe('rgb(255, 0, 0)')
// Default border width, which is not effected by bar.css that is not
loaded in /ssr
      expect(
        await browser.eval(
`window.getComputedStyle(document.querySelector('.text')).borderWidth`
        )
      ).toBe('1px')
    })
  })

it('should not throw with accessing to ALS in preload css', async () =>
{
    const output = next.cliOutput
    expect(output).not.toContain('was called outside a request scope')
  })
})`
- ID 293: `test/e2e/app-dir/emotion-js/index.test.ts` — `describe('app
dir - emotion-js', () => {
  const { next } = nextTestSetup({
    files: __dirname,
    dependencies: {
      '@emotion/react': 'latest',
      '@emotion/cache': 'latest',
    },
  })

it('should render emotion-js css with compiler.emotion option
correctly', async () => {
    const browser = await next.browser('/')
    const el = browser.elementByCss('h1')
    expect(await el.text()).toBe('Blue')
    await check(
      async () =>
        await browser.eval(
          `window.getComputedStyle(document.querySelector('h1')).color`
        ),
      'rgb(0, 0, 255)'
    )

    const el2 = browser.elementByCss('p')
    expect(await el2.text()).toBe('Red')
    await check(
      async () =>
        await browser.eval(
          `window.getComputedStyle(document.querySelector('p')).color`
        ),
      'rgb(255, 0, 0)'
    )
  })
})`
- ID 294:
`test/e2e/app-dir/global-error/with-style-import/index.test.ts` —
`describe('app dir - global error - with style import', () => {
  const { next, isNextDev } = nextTestSetup({
    files: __dirname,
  })

  it('should render global error with correct styles', async () => {
    const browser = await next.browser('/')

    if (isNextDev) {
      await testDev(browser, /Root Layout Error/)
      return
    }

    const h2 = await browser.elementByCss('h2')
expect(await h2.getComputedCss('color')).toBe('rgb(255, 255, 0)') //
yellow
  })
})`
- ID 301: `test/e2e/app-dir/not-found/css-precedence/index.test.ts` —
`describe('not-found app dir css', () => {
  const { next } = nextTestSetup({
    files: __dirname,
    dependencies: {
      sass: 'latest',
    },
  })

it('should load css while navigation between not-found and page', async
() => {
    const browser = await next.browser('/')
    await check(
      async () =>
        await browser.eval(

`window.getComputedStyle(document.querySelector('#go-to-404')).backgroundColor`
        ),
      'rgb(0, 128, 0)'
    )
    await browser.elementByCss('#go-to-404').click()
    await browser.waitForElementByCss('#go-to-index')
    await check(
      async () =>
        await browser.eval(

`window.getComputedStyle(document.querySelector('#go-to-index')).backgroundColor`
        ),
      'rgb(0, 128, 0)'
    )
    await browser.elementByCss('#go-to-index').click()
    await browser.waitForElementByCss('#go-to-404')
    await check(
      async () =>
        await browser.eval(

`window.getComputedStyle(document.querySelector('#go-to-404')).backgroundColor`
        ),
      'rgb(0, 128, 0)'
    )
  })
})`
- ID 308:
`test/e2e/app-dir/turbopack-postcss-multiple-configs/turbopack-postcss-multiple-configs.test.ts`
— `describe('turbopack-postcss-multiple-configs', () => {
  const { next, isTurbopack } = nextTestSetup({
    files: __dirname,
// Per-directory PostCSS config resolution is a Turbopack-only feature
// (turbopackLocalPostcssConfig). Webpack does not support this feature
and
// does not accept function-valued PostCSS plugins, so skip
non-Turbopack runs.
    skipStart: true,
  })

  if (!isTurbopack) {
    it('should only run with Turbopack', () => {})
    return
  }

  beforeAll(async () => {
    await next.start()
  })

// Each directory's postcss.config.js passes a unique color option to
the
  // shared plugin, which replaces `color: red` with the given color.
  // In production mode the CSS minifier may shorten named colors to hex
  // (e.g. blue → #00f), so we match on patterns that cover both forms.
  const DIR_COLORS: Record<number, string | RegExp> = {
    1: /blue|#00f/,
    2: /purple|#800080/,
    3: /orange|#ffa500/,
    4: /cyan|#0ff/,
    5: /magenta|#f0f/,
  }

  const DIRS = 5
  const FILES_PER_DIR = 3

it('should render all elements with CSS module classes applied', async
() => {
    const $ = await next.render$('/')

    for (let dir = 1; dir <= DIRS; dir++) {
      for (let file = 1; file <= FILES_PER_DIR; file++) {
        const padded = String(file).padStart(2, '0')
        const id = `dir${dir}-file${padded}`
        const el = $(`#${id}`)
        expect(el.length).toBe(1)
        expect(el.text().trim()).toBe(`dir${dir} file${padded}`)
        expect(el.attr('class')).toBeTruthy()
      }
    }
  })

it('should apply per-directory PostCSS transforms with distinct colors',
async () => {
    const cssContent = await collectCss(next)

    // Each directory's PostCSS config passes a unique color option.
    // Verify every expected color appears in the output.
    for (const [, pattern] of Object.entries(DIR_COLORS)) {
      expect(cssContent).toMatch(pattern)
    }

    // No original `color: red` should remain — all were transformed.
    expect(cssContent).not.toMatch(/color\s*:\s*red/)

// The old hardcoded green should NOT appear, proving options are used.
    expect(cssContent).not.toMatch(/green|#0f0|#008000/)
  })
})`
- ID 317: `test/e2e/image-optimizer/image-optimizer.test.ts` —
`describe('Server support for trailingSlash in next.config.js', () => {
    const { next } = nextTestSetup({
      files: join(__dirname, 'app'),
      nextConfig: {
        trailingSlash: true,
        images: {
          imageSizes: [8, 16, 32, 48, 64, 96, 128, 256, 384],
          qualities: [70, 75],
        },
      },
    })

it('should return successful response for original loader', async () =>
{
      const query = { url: '/test.png', w: 8, q: 70 }
const res = await next.fetch(`/_next/image/?${toQueryString(query)}`)
      expect(res.status).toBe(200)
    })
  })`
- ID 329: `test/e2e/next-image-legacy/default/default-static.test.ts` —
`describe('Static Image Component Tests', () => {
  const { next, isTurbopack } = nextTestSetup({
    files: __dirname,
  })

  let browser: Playwright
  let html: string

  beforeAll(async () => {
    html = await next.render('/static-img')
    browser = await next.browser('/static-img')
  })

it('Should allow an image with a static src to omit height and width',
async () => {
    expect(await browser.elementById('basic-static')).toBeTruthy()
    expect(await browser.elementById('blur-png')).toBeTruthy()
    expect(await browser.elementById('blur-webp')).toBeTruthy()
    expect(await browser.elementById('blur-avif')).toBeTruthy()
    expect(await browser.elementById('blur-jpg')).toBeTruthy()
    expect(await browser.elementById('static-svg')).toBeTruthy()
    expect(await browser.elementById('static-gif')).toBeTruthy()
    expect(await browser.elementById('static-bmp')).toBeTruthy()
    expect(await browser.elementById('static-ico')).toBeTruthy()
    expect(await browser.elementById('static-unoptimized')).toBeTruthy()
  })
  ;(isNextStart ? it : it.skip)(
    'Should use immutable cache-control header for static import',
    async () => {
      await browser.eval(
        `document.getElementById("basic-static").scrollIntoView()`
      )
      await new Promise((resolve) => setTimeout(resolve, 1000))
      const url = await browser.eval(
        `document.getElementById("basic-static").src`
      )
      const res = await fetch(url)
      expect(res.headers.get('cache-control')).toBe(
        'public, max-age=315360000, immutable'
      )
    }
  )
  ;(isNextStart ? it : it.skip)(
    'Should use immutable cache-control header even when unoptimized',
    async () => {
      await browser.eval(
        `document.getElementById("static-unoptimized").scrollIntoView()`
      )
      await new Promise((resolve) => setTimeout(resolve, 1000))
      const url = await browser.eval(
        `document.getElementById("static-unoptimized").src`
      )
      const res = await fetch(url)
      expect(res.headers.get('cache-control')).toBe(
        'public, max-age=31536000, immutable'
      )
    }
  )

it('Should automatically provide an image height and width', async () =>
{
    expect(html).toContain('width:400px;height:300px')
  })

it('Should allow provided width and height to override intrinsic', async
() => {
    expect(html).toContain('width:200px;height:200px')
    expect(html).not.toContain('width:400px;height:400px')
  })

it('Should add a blur placeholder to statically imported jpg', async ()
=> {
    const $ = cheerio.load(html)
    const style = $('#basic-static').attr('style')
    if (isNextDev && !isTurbopack) {
// In webpack dev, `next/legacy/image` emits a dynamic blur URL via the
// image optimizer route instead of an inlined base64 data URL, to avoid
      // slowing down the dev server (see
// `packages/next/src/build/webpack/loaders/next-image-loader/blur.ts`).
      expect(replaceBlurUrl(style)).toMatchInlineSnapshot(

`"position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100%;max-height:100%;background-size:cover;background-position:0%
0%;filter:blur(20px);background-image:url("<REPLACED_BLUR_URL>")"`
      )
    } else {
      expect(replaceDataUrl(style)).toMatchInlineSnapshot(

`"position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100%;max-height:100%;background-size:cover;background-position:0%
0%;filter:blur(20px);background-image:url("data:<REPLACED>")"`
      )
    }
  })

it('Should add a blur placeholder to statically imported png', async ()
=> {
    const $ = cheerio.load(html)
    const style = $('#basic-static')[2].attribs.style
    if (isTurbopack) {
      expect(style).toMatchInlineSnapshot(

`"position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100%;max-height:100%;background-size:cover;background-position:0%
0%;filter:blur(20px);background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAICAYAAAA870V8AAAARUlEQVR42l3MoQ0AQQhE0XG7xWwIJSBIKBRJOZRBEXOWnPjimQ8AXC3ce+nuPOcQEcHuppkRVcWZYWYSIkJV5XvvN9j4AFZHJTnjDHb/AAAAAElFTkSuQmCC")"`
      )
    } else if (isNextDev) {
// In webpack dev, `next/legacy/image` emits a dynamic blur URL via the
// image optimizer route instead of an inlined base64 data URL, to avoid
      // slowing down the dev server (see
// `packages/next/src/build/webpack/loaders/next-image-loader/blur.ts`).
      expect(replaceBlurUrl(style)).toMatchInlineSnapshot(

`"position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100%;max-height:100%;background-size:cover;background-position:0%
0%;filter:blur(20px);background-image:url("<REPLACED_BLUR_URL>")"`
      )
    } else {
// In webpack start, the exact base64 output of the blur placeholder
// depends on the environment's sharp/libvips version, so normalize the
      // data URL contents to only assert the data URL prefix.
      expect(replaceDataUrl(style)).toMatchInlineSnapshot(

`"position:absolute;top:0;left:0;bottom:0;right:0;box-sizing:border-box;padding:0;border:none;margin:auto;display:block;width:0;height:0;min-width:100%;max-width:100%;min-height:100%;max-height:100%;background-size:cover;background-position:0%
0%;filter:blur(20px);background-image:url("data:<REPLACED>")"`
      )
    }
  })

  it('should load direct imported image', async () => {
const src = await
browser.elementById('basic-static').getAttribute('src')
    expect(src).toMatch(

/_next\/image\?url=%2F_next%2Fstatic%2F(immutable%2F)?media%2Ftest-rect(.+)\.jpg&w=828&q=75/
    )
    const fullSrc = new URL(src, next.url)
    const res = await fetch(fullSrc)
    expect(res.status).toBe(200)
  })

  it('should load staticprops imported image', async () => {
    const src = await browser
      .elementById('basic-staticprop')
      .getAttribute('src')
    expect(src).toMatch(

/_next\/image\?url=%2F_next%2Fstatic%2F(immutable%2F)?media%2Fexif-rotation(.+)\.jpg&w=256&q=75/
    )
    const fullSrc = new URL(src, next.url)
    const res = await fetch(fullSrc)
    expect(res.status).toBe(200)
  })
})`
- ID 345: `test/e2e/next-image-svgo-webpack/svgo-webpack.test.ts` —
`describe('svgo-webpack loader', () => {
  const { next } = nextTestSetup({
    files: __dirname,
    dependencies: {
      '@svgr/webpack': '8.1.0',
    },
  })

it('should render an SVG that is transformed by @svgr/webpack into a
React component (pages router)', async () => {
    const browser = await next.browser('/pages')
    expect(await browser.elementByCss('svg')).toBeDefined()
  })

it('should render an SVG that is transformed by @svgr/webpack into a
React component (app router)', async () => {
    const browser = await next.browser('/')
    expect(await browser.elementByCss('svg')).toBeDefined()
  })
})`
- ID 347: `test/e2e/styled-jsx-dynamic/index.test.ts` —
`describe('styled-jsx dynamic styles SSR', () => {
  const { next } = nextTestSetup({
    files: __dirname,
  })

// Dynamic styled-jsx (with interpolated expressions) produces numeric
class
// names at runtime via the DJB2 hash in styled-jsx's computeId
function.
// This pattern matches production deployments where all jsx class names
// are numeric (e.g. jsx-2267428885) rather than hex
(jsx-f36313d9f07883b7).
it('should contain dynamic styled-jsx styles during SSR', async () => {
    const html = await next.render('/')

    // Dynamic styled-jsx produces numeric class names at runtime
    const numericClasses = html.match(/\bjsx-\d+\b/g) || []
    console.log('Numeric jsx classes:', [...new Set(numericClasses)])
    expect(numericClasses.length).toBeGreaterThan(0)

    // All dynamic styles should be present as inline <style> tags
    expect(html).toMatch(/color:.*?green/) // main page
    expect(html).toMatch(/color:.*?blue/) // DynamicStyled
    expect(html).toMatch(/background-color:.*?navy/) // header
    expect(html).toMatch(/color:.*?purple/) // footer
  })
})`
- ID 348: `test/e2e/styled-jsx/index.test.ts` — `describe('styled-jsx',
() => {
  const { next } = nextTestSetup({
    files: __dirname,
    dependencies: {
      'styled-jsx': '5.0.0', // styled-jsx on user side
    },
  })

  it('should contain styled-jsx styles during SSR', async () => {
    const html = await next.render('/')
    expect(html).toMatch(/color:.*?red/)
    expect(html).toMatch(/color:.*?cyan/)
  })

  it('should render styles during CSR', async () => {
    const browser = await next.browser('/')
    const color = await browser.eval(
      `getComputedStyle(document.querySelector('button')).color`
    )

    expect(color).toMatch('0, 255, 255')
  })

  it('should render styles inside TypeScript', async () => {
    const browser = await next.browser('/typescript')
    const color = await browser.eval(
      `getComputedStyle(document.querySelector('button')).color`
    )

    expect(color).toMatch('255, 0, 0')
  })
})`

</details>

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

- `test/e2e/image-optimizer/image-optimizer.test.ts` — `describe('Server
support for trailingSlash in next.config.js', () => {`:
[normal](https://github.com/vercel/next.js/actions/runs/34426784928/job/102715630953),
[cache](https://github.com/vercel/next.js/actions/runs/34426784928/job/102715630856).
- `test/e2e/next-image-legacy/default/default-static.test.ts` —
`describe('Static Image Component Tests', () => {`:
[normal](https://github.com/vercel/next.js/actions/runs/34426784928/job/102715630923),
[cache](https://github.com/vercel/next.js/actions/runs/34426784928/job/102715630827).

</details>

<!-- NEXT_JS_LLM -->
2026-09-15 10:29:07 -07:00
..