Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .circleci/src/pipeline/@pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ commands:
name: Set environment variable to determine whether or not to persist artifacts
command: |
echo "Setting SHOULD_PERSIST_ARTIFACTS variable"
echo 'if ! [[ "$CIRCLE_BRANCH" != "develop" && "$CIRCLE_BRANCH" != "release/"* && "$CIRCLE_BRANCH" != "chore/remove_unused_anchors" ]]; then
echo 'if ! [[ "$CIRCLE_BRANCH" != "develop" && "$CIRCLE_BRANCH" != "release/"* && "$CIRCLE_BRANCH" != "feat/support_next_16" ]]; then
export SHOULD_PERSIST_ARTIFACTS=true
fi' >> "$BASH_ENV"
# You must run `setup_should_persist_artifacts` command and be using bash before running this command
Expand Down
2 changes: 1 addition & 1 deletion .circleci/src/pipeline/workflows/@main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ linux-x64:
- equal: [ develop, << pipeline.git.branch >> ]
# use the following branch as well to ensure that v8 snapshot cache updates are fully tested
- equal: [ 'update-v8-snapshot-cache-on-develop', << pipeline.git.branch >> ]
- equal: [ 'chore/remove_unused_anchors', << pipeline.git.branch >> ]
- equal: [ 'feat/support_next_16', << pipeline.git.branch >> ]
- matches:
pattern: /^release\/\d+\.\d+\.\d+$/
value: << pipeline.git.branch >>
Expand Down
8 changes: 6 additions & 2 deletions cli/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
<!-- See the ../guides/writing-the-cypress-changelog.md for details on writing the changelog. -->
## 15.6.1
## 15.7.0

_Released 11/18/2025 (PENDING)_

**Features:**

- `Next.js` version 16 is now supported within component testing. Addresses [#32857](https://github.com/cypress-io/cypress/issues/32857).

**Bugfixes:**

- 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).
Expand All @@ -19,7 +23,7 @@ _Released 11/4/2025_

**Features:**

- 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).
- 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).
- [`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).

**Bugfixes:**
Expand Down
145 changes: 31 additions & 114 deletions npm/webpack-dev-server/src/helpers/nextHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Module from 'module'
import type { Configuration } from 'webpack'
import * as fs from 'fs'
import * as path from 'path'
import semver from 'semver'
import type { PresetHandlerResult, WebpackDevServerConfig } from '../devServer'
import { cypressWebpackPath, getMajorVersion, ModuleClass, SourcedDependency, SourcedWebpack, sourceFramework, sourceHtmlWebpackPlugin, sourceWebpackDevServer } from './sourceRelativeWebpackModules'

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

/**
* Types for `getNextJsBaseWebpackConfig` based on version:
* - v11.1.4
* - v14.0.0, v15.0.0, and v16.0.0
[
dir: string,
options: {
buildId: string
config: NextConfigComplete
dev?: boolean
isServer?: boolean
pagesDir: string
target?: string
reactProductionProfiling?: boolean
entrypoints: WebpackEntrypoints
rewrites: CustomRoutes['rewrites']
isDevFallback?: boolean
runWebpackSpan: Span
}
]

* - v12.0.0 = Same as v11.1.4

* - v12.1.6
[
dir: string,
options: {
buildId: string
config: NextConfigComplete
compilerType: 'client' | 'server' | 'edge-server'
dev?: boolean
entrypoints: webpack5.EntryObject
hasReactRoot: boolean
isDevFallback?: boolean
pagesDir: string
reactProductionProfiling?: boolean
rewrites: CustomRoutes['rewrites']
runWebpackSpan: Span
target?: string
}
]

* - v13.0.0
[
dir: string,
options: {
buildId: string
config: NextConfigComplete
compilerType: CompilerNameValues
dev?: boolean
entrypoints: webpack.EntryObject
hasReactRoot: boolean
isDevFallback?: boolean
pagesDir?: string
reactProductionProfiling?: boolean
rewrites: CustomRoutes['rewrites']
runWebpackSpan: Span
target?: string
appDir?: string
middlewareMatchers?: MiddlewareMatcher[]
}
]

* - v13.0.1
[
dir: string,
options: {
options: {
buildId: string
encryptionKey: string
config: NextConfigComplete
compilerType: CompilerNameValues
dev?: boolean
Expand All @@ -147,41 +89,27 @@ function getNextJsPackages (devServerConfig: WebpackDevServerConfig) {
pagesDir?: string
reactProductionProfiling?: boolean
rewrites: CustomRoutes['rewrites']
originalRewrites?: CustomRoutes['rewrites']
originalRedirects?: CustomRoutes['redirects']
runWebpackSpan: Span
target?: string
appDir?: string
middlewareMatchers?: MiddlewareMatcher[]
}
]

* - v13.2.1
[
dir: string,
options: {
buildId: string
config: NextConfigComplete
compilerType: CompilerNameValues
dev?: boolean
entrypoints: webpack.EntryObject
isDevFallback?: boolean
pagesDir?: string
reactProductionProfiling?: boolean
rewrites: CustomRoutes['rewrites']
runWebpackSpan: Span
target?: string
appDir?: string
middlewareMatchers?: MiddlewareMatcher[]
noMangling?: boolean
jsConfig: any
resolvedBaseUrl: string | undefined
supportedBrowsers: string[] | undefined
clientRouterFilters?: {
staticFilter: ReturnType<
import('../shared/lib/bloom-filter').BloomFilter['export']
>
dynamicFilter: ReturnType<
import('../shared/lib/bloom-filter').BloomFilter['export']
>
middlewareMatchers?: ProxyMatcher[]
noMangling?: boolean
jsConfig: any
jsConfigPath?: string
resolvedBaseUrl: ResolvedBaseUrl
supportedBrowsers: string[] | undefined
clientRouterFilters?: {
staticFilter: ReturnType<
import('../shared/lib/bloom-filter').BloomFilter['export']
>
dynamicFilter: ReturnType<
import('../shared/lib/bloom-filter').BloomFilter['export']
>
}
fetchCacheKeyPrefix?: string
isCompileMode?: boolean
previewProps: NonNullable<(typeof NextBuildContext)['previewProps']>;
}
}
]
Expand Down Expand Up @@ -210,7 +138,7 @@ async function loadWebpackConfig (devServerConfig: WebpackDevServerConfig): Prom
// Client webpack config for Next.js > 12.1.5
compilerType: 'client',
// Required for Next.js > 13
hasReactRoot: reactVersion === 18,
hasReactRoot: reactVersion && reactVersion >= 18,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Boolean Logic Fails with Undefined React Version

The hasReactRoot property is set to undefined when getReactVersion fails to find React, rather than false. The expression reactVersion && reactVersion >= 18 evaluates to undefined when reactVersion is undefined, which may cause unexpected behavior in Next.js webpack configuration that expects a boolean value. This should explicitly coerce to boolean using Boolean(reactVersion && reactVersion >= 18) or reactVersion ? reactVersion >= 18 : false.

Fix in Cursor Fix in Web

// Required for Next.js > 13.2.0 to respect TS/JS config
jsConfig: jsConfigResult.jsConfig,
// Required for Next.js > 13.2.0 to respect tsconfig.compilerOptions.baseUrl
Expand Down Expand Up @@ -338,34 +266,23 @@ function sourceNextWebpack (devServerConfig: WebpackDevServerConfig, framework:
throw e
}

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

try {
const nextConfig = require(path.resolve(devServerConfig.cypressConfig.projectRoot, 'next.config.js'))

debug('NextWebpack: next.config.js found - %o', nextConfig)

if (nextConfig.webpack5 === false) {
webpack5 = false
}
} catch (e) {
// No next.config.js, assume webpack 5
// If Next.js is 16 and greater, webpack.js runs the required code previously inside init() on require().
// init() no longer exists and has the same affect on import, so we don't/can't invoke it
if (semver.lt(framework.packageJson.version, '16.0.0')) {
// for next 15 and down, we need to initialize the webpack module
webpackModule.init(true)
}

debug('NextWebpack: webpack5 - %s', webpack5)
webpackModule.init(webpack5)

const packageJson = require(webpackJsonPath)

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

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

Expand Down
20 changes: 10 additions & 10 deletions packages/scaffold-config/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ We will also attempt to scaffold a configuration file for projects using React a

### Supported Frameworks and Libraries

| Name | Version| Dev Server | Version | Library | Component Adaptor | Example Project |
| ---------------- | -------| ---------- | ---------- | ------------------ | -------------------------- | ------------------------------------------------------------------- |
| React | - | Vite | 5, 6, 7 | React 18, 19 | `@cypress/react@latest` | [Link](../../system-tests/projects/react-vite-ts-configured) |
| React | - | Webpack | 5 | React 18, 19 | `@cypress/vue@latest` | [Link](../../system-tests/projects/react18) |
| Vue | - | Vite | 5, 6, 7 | Vue 3 | `@cypress/react@latest` | [Link](../../system-tests/projects/vue3-vite-ts-configured) |
| Vue | - | Webpack | 5 | Vue 3 | `@cypress/vue@latest` | [Link](../../system-tests/projects/vue3-webpack-ts-configured) |
| Angular | - | Webpack | 5 | Angular 17, 18, 19 | `@cypress/angular@latest` | [Link](../../system-tests/projects/angular-cli-configured) |
| Svelte | - | Vite | 5, 6, 7 | Svelte 5 | `@cypress/svelte@latest` | [Link](../../system-tests/projects/svelte-vite-configured) |
| Svelte | - | Webpack | 5 | Svelte 5 | `@cypress/svelte@latest` | [Link](../../system-tests/projects/svelte-webpack-configured) |
| Next.js | 14, 15 | Webpack | 5 | React 18, 19 | `@cypress/react@latest` | [Link](../../system-tests/projects/nextjs-configured) |
| Name | Version | Dev Server | Version | Library | Component Adaptor | Example Project |
| ---------------- | -----------| ---------- | ---------- | ------------------ | -------------------------- | ------------------------------------------------------------------- |
| React | - | Vite | 5, 6, 7 | React 18, 19 | `@cypress/react@latest` | [Link](../../system-tests/projects/react-vite-ts-configured) |
| React | - | Webpack | 5 | React 18, 19 | `@cypress/vue@latest` | [Link](../../system-tests/projects/react18) |
| Vue | - | Vite | 5, 6, 7 | Vue 3 | `@cypress/react@latest` | [Link](../../system-tests/projects/vue3-vite-ts-configured) |
| Vue | - | Webpack | 5 | Vue 3 | `@cypress/vue@latest` | [Link](../../system-tests/projects/vue3-webpack-ts-configured) |
| Angular | - | Webpack | 5 | Angular 17, 18, 19 | `@cypress/angular@latest` | [Link](../../system-tests/projects/angular-cli-configured) |
| Svelte | - | Vite | 5, 6, 7 | Svelte 5 | `@cypress/svelte@latest` | [Link](../../system-tests/projects/svelte-vite-configured) |
| Svelte | - | Webpack | 5 | Svelte 5 | `@cypress/svelte@latest` | [Link](../../system-tests/projects/svelte-webpack-configured) |
| Next.js | 14, 15, 16 | Webpack | 5 | React 18, 19 | `@cypress/react@latest` | [Link](../../system-tests/projects/nextjs-configured) |

### Adding More Projects

Expand Down
2 changes: 1 addition & 1 deletion packages/scaffold-config/src/dependencies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export const WIZARD_DEPENDENCY_NEXT = {
// next 15.0.0 -> 15.0.3 use the React 19 RC as a dependency
// Since we do not support the React 19 RC and only the official React 19 release,
// we will only be supporting Next.js 15.0.4 officially (the others previously mentioned should still work)
minVersion: '^14.0.0 || ^15.0.4',
minVersion: '^14.0.0 || ^15.0.4 || ^16.0.0',
} as const

export const WIZARD_DEPENDENCY_ANGULAR_CLI = {
Expand Down
Loading