Setting up Cypress with Next.js
Cypress is a test runner used for End-to-End (E2E) and Component Testing. This page will show you how to set up Cypress with Next.js and write your first tests.
Warning:
- For component testing, Cypress currently does not support Next.js version 14 and
asyncServer Components. These issues are being tracked. For now, component testing works with Next.js version 13, and we recommend E2E testing forasyncServer Components.- Cypress currently does not support TypeScript version 5 with
moduleResolution:"bundler". This issue is being tracked.
Quickstart
You can use create-next-app with the with-cypress example to quickly get started.
1npx create-next-app@latest --example with-cypress with-cypress-app
Manual setup
To manually set up Cypress, install cypress as a dev dependency:
1npm install -D cypress2# or3yarn add -D cypress4# or5pnpm install -D cypress
Add the Cypress open command to the package.json scripts field:
1{2"scripts": {3"dev": "next dev",4"build": "next build",5"start": "next start",6"lint": "next lint",7"cypress:open": "cypress open"8}9}
Run Cypress for the first time to open the Cypress testing suite:
1npm run cypress:open
You can choose to configure E2E Testing and/or Component Testing. Selecting any of these options will automatically create a cypress.config.js file and a cypress folder in your project.
Creating your first Cypress E2E test
Ensure your cypress.config.js file has the following configuration:
1import { defineConfig } from 'cypress'23export default defineConfig({4e2e: {5setupNodeEvents(on, config) {},6},7})
1const { defineConfig } = require('cypress')23module.exports = defineConfig({4e2e: {5setupNodeEvents(on, config) {},6},7})
Then, create two new Next.js files:
1import Link from 'next/link'23export default function Page() {4return (5<div>6<h1>Home</h1>7<Link href="/about">About</Link>8</div>9)10}
1import Link from 'next/link'23export default function Page() {4return (5<div>6<h1>About</h1>7<Link href="/">Home</Link>8</div>9)10}
Add a test to check your navigation is working correctly:
1describe('Navigation', () => {2it('should navigate to the about page', () => {3// Start from the index page4cy.visit('http://localhost:3000/')56// Find a link with an href attribute containing "about" and click it7cy.get('a[href*="about"]').click()89// The new url should include "/about"10cy.url().should('include', '/about')1112// The new page should contain an h1 with "About"13cy.get('h1').contains('About')14})15})
Running E2E Tests
Cypress will simulate a user navigating your application, this requires your Next.js server to be running. We recommend running your tests against your production code to more closely resemble how your application will behave.
Run npm run build && npm run start to build your Next.js application, then run npm run cypress:open in another terminal window to start Cypress and run your E2E testing suite.
Good to know:
- You can use
cy.visit("/")instead ofcy.visit("http://localhost:3000/")by addingbaseUrl: 'http://localhost:3000'to thecypress.config.jsconfiguration file.- Alternatively, you can install the
start-server-and-testpackage to run the Next.js production server in conjuction with Cypress. After installation, add"test": "start-server-and-test start http://localhost:3000 cypress"to yourpackage.jsonscripts field. Remember to rebuild your application after new changes.
Creating your first Cypress component test
Component tests build and mount a specific component without having to bundle your whole application or start a server.
Select Component Testing in the Cypress app, then select Next.js as your front-end framework. A cypress/component folder will be created in your project, and a cypress.config.js file will be updated to enable component testing.
Ensure your cypress.config.js file has the following configuration:
1import { defineConfig } from 'cypress'23export default defineConfig({4component: {5devServer: {6framework: 'next',7bundler: 'webpack',8},9},10})
1const { defineConfig } = require('cypress')23module.exports = defineConfig({4component: {5devServer: {6framework: 'next',7bundler: 'webpack',8},9},10})
Assuming the same components from the previous section, add a test to validate a component is rendering the expected output:
1import Page from '../../app/page'23describe('<Page />', () => {4it('should render and display expected content', () => {5// Mount the React component for the Home page6cy.mount(<Page />)78// The new page should contain an h1 with "Home"9cy.get('h1').contains('Home')1011// Validate that a link with the expected URL is present12// Following the link is better suited to an E2E test13cy.get('a[href="/about"]').should('be.visible')14})15})
Good to know:
- Cypress currently doesnโt support component testing for
asyncServer Components. We recommend using E2E testing.- Since component tests do not require a Next.js server, features like
<Image />that rely on a server being available may not function out-of-the-box.
Running Component Tests
Run npm run cypress:open in your terminal to start Cypress and run your component testing suite.
Continuous Integration (CI)
In addition to interactive testing, you can also run Cypress headlessly using the cypress run command, which is better suited for CI environments:
1{2"scripts": {3//...4"e2e": "start-server-and-test dev http://localhost:3000 \"cypress open --e2e\"",5"e2e:headless": "start-server-and-test dev http://localhost:3000 \"cypress run --e2e\"",6"component": "cypress open --component",7"component:headless": "cypress run --component"8}9}
You can learn more about Cypress and Continuous Integration from these resources: