Skip to content

Commit 8ce0a5d

Browse files
committed
feat: support Next.js 16 inside component testing
1 parent 607050d commit 8ce0a5d

File tree

5 files changed

+40
-119
lines changed

5 files changed

+40
-119
lines changed

.circleci/src/pipeline/@pipeline.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ commands:
121121
name: Set environment variable to determine whether or not to persist artifacts
122122
command: |
123123
echo "Setting SHOULD_PERSIST_ARTIFACTS variable"
124-
echo 'if ! [[ "$CIRCLE_BRANCH" != "develop" && "$CIRCLE_BRANCH" != "release/"* && "$CIRCLE_BRANCH" != "chore/remove_unused_anchors" ]]; then
124+
echo 'if ! [[ "$CIRCLE_BRANCH" != "develop" && "$CIRCLE_BRANCH" != "release/"* && "$CIRCLE_BRANCH" != "feat/support_next_16" ]]; then
125125
export SHOULD_PERSIST_ARTIFACTS=true
126126
fi' >> "$BASH_ENV"
127127
# You must run `setup_should_persist_artifacts` command and be using bash before running this command

.circleci/src/pipeline/workflows/@main.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ linux-x64:
44
- equal: [ develop, << pipeline.git.branch >> ]
55
# use the following branch as well to ensure that v8 snapshot cache updates are fully tested
66
- equal: [ 'update-v8-snapshot-cache-on-develop', << pipeline.git.branch >> ]
7-
- equal: [ 'chore/remove_unused_anchors', << pipeline.git.branch >> ]
7+
- equal: [ 'feat/support_next_16', << pipeline.git.branch >> ]
88
- matches:
99
pattern: /^release\/\d+\.\d+\.\d+$/
1010
value: << pipeline.git.branch >>

cli/CHANGELOG.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
<!-- See the ../guides/writing-the-cypress-changelog.md for details on writing the changelog. -->
2-
## 15.6.1
2+
## 15.7.0
33

44
_Released 11/18/2025 (PENDING)_
55

6+
**Features:**
7+
8+
- `Next.js` version 16 is now supported within component testing. Addresses [#32857](https://github.com/cypress-io/cypress/issues/32857).
9+
610
**Bugfixes:**
711

812
- Fixed an issue where [`cy.wrap()`](https://docs.cypress.io/api/commands/wrap) would cause infinite recursion and freeze the Cypress App when called with objects containing circular references. Fixes [#24715](https://github.com/cypress-io/cypress/issues/24715). Addressed in [#32917](https://github.com/cypress-io/cypress/pull/32917).
@@ -19,7 +23,7 @@ _Released 11/4/2025_
1923

2024
**Features:**
2125

22-
- Added a 'Self-healed' badge to the Command Log when [`cy.prompt()`](https://docs.cypress.io/api/commands/prompt) steps automatically recover after the element they need is not found in the cache. Addressed in [#32802](https://github.com/cypress-io/cypress/pull/32802).
26+
- Added a 'Self-healed' badge to the Command Log when [`cy.prompt()`](https://docs.cypress.io/api/commands/prompt) steps automatically recover after the element they need is not found in the cache. Addressed in [#32802](https://github.com/cypress-io/cypress/pull/32802).
2327
- [`cy.prompt()`](https://docs.cypress.io/api/commands/prompt) will now show a warning in the `Get code` modal when there are unsaved changes in `Studio` that will be lost if the user saves the generated code. Addressed in [#32741](https://github.com/cypress-io/cypress/pull/32741).
2428

2529
**Bugfixes:**

npm/webpack-dev-server/src/helpers/nextHandler.ts

Lines changed: 31 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import Module from 'module'
33
import type { Configuration } from 'webpack'
44
import * as fs from 'fs'
55
import * as path from 'path'
6+
import semver from 'semver'
67
import type { PresetHandlerResult, WebpackDevServerConfig } from '../devServer'
78
import { cypressWebpackPath, getMajorVersion, ModuleClass, SourcedDependency, SourcedWebpack, sourceFramework, sourceHtmlWebpackPlugin, sourceWebpackDevServer } from './sourceRelativeWebpackModules'
89

@@ -74,71 +75,12 @@ function getNextJsPackages (devServerConfig: WebpackDevServerConfig) {
7475

7576
/**
7677
* Types for `getNextJsBaseWebpackConfig` based on version:
77-
* - v11.1.4
78+
* - v14.0.0, v15.0.0, and v16.0.0
7879
[
7980
dir: string,
80-
options: {
81-
buildId: string
82-
config: NextConfigComplete
83-
dev?: boolean
84-
isServer?: boolean
85-
pagesDir: string
86-
target?: string
87-
reactProductionProfiling?: boolean
88-
entrypoints: WebpackEntrypoints
89-
rewrites: CustomRoutes['rewrites']
90-
isDevFallback?: boolean
91-
runWebpackSpan: Span
92-
}
93-
]
94-
95-
* - v12.0.0 = Same as v11.1.4
96-
97-
* - v12.1.6
98-
[
99-
dir: string,
100-
options: {
101-
buildId: string
102-
config: NextConfigComplete
103-
compilerType: 'client' | 'server' | 'edge-server'
104-
dev?: boolean
105-
entrypoints: webpack5.EntryObject
106-
hasReactRoot: boolean
107-
isDevFallback?: boolean
108-
pagesDir: string
109-
reactProductionProfiling?: boolean
110-
rewrites: CustomRoutes['rewrites']
111-
runWebpackSpan: Span
112-
target?: string
113-
}
114-
]
115-
116-
* - v13.0.0
117-
[
118-
dir: string,
119-
options: {
120-
buildId: string
121-
config: NextConfigComplete
122-
compilerType: CompilerNameValues
123-
dev?: boolean
124-
entrypoints: webpack.EntryObject
125-
hasReactRoot: boolean
126-
isDevFallback?: boolean
127-
pagesDir?: string
128-
reactProductionProfiling?: boolean
129-
rewrites: CustomRoutes['rewrites']
130-
runWebpackSpan: Span
131-
target?: string
132-
appDir?: string
133-
middlewareMatchers?: MiddlewareMatcher[]
134-
}
135-
]
136-
137-
* - v13.0.1
138-
[
139-
dir: string,
140-
options: {
81+
options: {
14182
buildId: string
83+
encryptionKey: string
14284
config: NextConfigComplete
14385
compilerType: CompilerNameValues
14486
dev?: boolean
@@ -147,41 +89,27 @@ function getNextJsPackages (devServerConfig: WebpackDevServerConfig) {
14789
pagesDir?: string
14890
reactProductionProfiling?: boolean
14991
rewrites: CustomRoutes['rewrites']
92+
originalRewrites?: CustomRoutes['rewrites']
93+
originalRedirects?: CustomRoutes['redirects']
15094
runWebpackSpan: Span
151-
target?: string
15295
appDir?: string
153-
middlewareMatchers?: MiddlewareMatcher[]
154-
}
155-
]
156-
157-
* - v13.2.1
158-
[
159-
dir: string,
160-
options: {
161-
buildId: string
162-
config: NextConfigComplete
163-
compilerType: CompilerNameValues
164-
dev?: boolean
165-
entrypoints: webpack.EntryObject
166-
isDevFallback?: boolean
167-
pagesDir?: string
168-
reactProductionProfiling?: boolean
169-
rewrites: CustomRoutes['rewrites']
170-
runWebpackSpan: Span
171-
target?: string
172-
appDir?: string
173-
middlewareMatchers?: MiddlewareMatcher[]
174-
noMangling?: boolean
175-
jsConfig: any
176-
resolvedBaseUrl: string | undefined
177-
supportedBrowsers: string[] | undefined
178-
clientRouterFilters?: {
179-
staticFilter: ReturnType<
180-
import('../shared/lib/bloom-filter').BloomFilter['export']
181-
>
182-
dynamicFilter: ReturnType<
183-
import('../shared/lib/bloom-filter').BloomFilter['export']
184-
>
96+
middlewareMatchers?: ProxyMatcher[]
97+
noMangling?: boolean
98+
jsConfig: any
99+
jsConfigPath?: string
100+
resolvedBaseUrl: ResolvedBaseUrl
101+
supportedBrowsers: string[] | undefined
102+
clientRouterFilters?: {
103+
staticFilter: ReturnType<
104+
import('../shared/lib/bloom-filter').BloomFilter['export']
105+
>
106+
dynamicFilter: ReturnType<
107+
import('../shared/lib/bloom-filter').BloomFilter['export']
108+
>
109+
}
110+
fetchCacheKeyPrefix?: string
111+
isCompileMode?: boolean
112+
previewProps: NonNullable<(typeof NextBuildContext)['previewProps']>;
185113
}
186114
}
187115
]
@@ -210,7 +138,7 @@ async function loadWebpackConfig (devServerConfig: WebpackDevServerConfig): Prom
210138
// Client webpack config for Next.js > 12.1.5
211139
compilerType: 'client',
212140
// Required for Next.js > 13
213-
hasReactRoot: reactVersion === 18,
141+
hasReactRoot: reactVersion && reactVersion >= 18,
214142
// Required for Next.js > 13.2.0 to respect TS/JS config
215143
jsConfig: jsConfigResult.jsConfig,
216144
// Required for Next.js > 13.2.0 to respect tsconfig.compilerOptions.baseUrl
@@ -338,34 +266,23 @@ function sourceNextWebpack (devServerConfig: WebpackDevServerConfig, framework:
338266
throw e
339267
}
340268

341-
// Next 11 allows the choice of webpack@4 or webpack@5, depending on the "webpack5" property in their next.config.js
342-
// The webpackModule.init" for Next 11 returns a webpack@4 or webpack@4 compiler instance based on this boolean
343-
let webpack5 = true
344269
const importPath = path.join(path.dirname(webpackJsonPath), 'webpack.js')
345270
const webpackModule = require(importPath)
346271

347-
try {
348-
const nextConfig = require(path.resolve(devServerConfig.cypressConfig.projectRoot, 'next.config.js'))
349-
350-
debug('NextWebpack: next.config.js found - %o', nextConfig)
351-
352-
if (nextConfig.webpack5 === false) {
353-
webpack5 = false
354-
}
355-
} catch (e) {
356-
// No next.config.js, assume webpack 5
272+
// If Next.js is 16 and greater, webpack.js runs the required code previously inside init() on require().
273+
// init() no longer exists and has the same affect on import, so we don't/can't invoke it
274+
if (semver.lt(framework.packageJson.version, '16.0.0')) {
275+
// for next 15 and down, we need to initialize the webpack module
276+
webpackModule.init(true)
357277
}
358278

359-
debug('NextWebpack: webpack5 - %s', webpack5)
360-
webpackModule.init(webpack5)
361-
362279
const packageJson = require(webpackJsonPath)
363280

364281
webpack.importPath = importPath
365282
// The package.json of "next/dist/compiled/webpack/package.json" has no version so we supply the version for later use
366-
webpack.packageJson = { ...packageJson, version: webpack5 ? '5' : '4' }
283+
webpack.packageJson = { ...packageJson, version: '5' }
367284
webpack.module = webpackModule.webpack
368-
webpack.majorVersion = getMajorVersion(webpack.packageJson, [4, 5])
285+
webpack.majorVersion = getMajorVersion(webpack.packageJson, [5])
369286

370287
debug('NextWebpack: Successfully loaded NextWebpack - %o', webpack)
371288

packages/scaffold-config/src/dependencies.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ export const WIZARD_DEPENDENCY_NEXT = {
6161
// next 15.0.0 -> 15.0.3 use the React 19 RC as a dependency
6262
// Since we do not support the React 19 RC and only the official React 19 release,
6363
// we will only be supporting Next.js 15.0.4 officially (the others previously mentioned should still work)
64-
minVersion: '^14.0.0 || ^15.0.4',
64+
minVersion: '^14.0.0 || ^15.0.4 || ^16.0.0',
6565
} as const
6666

6767
export const WIZARD_DEPENDENCY_ANGULAR_CLI = {

0 commit comments

Comments
 (0)