Skip to content

Commit

Permalink
feat: support next 15 [run ci] (#30654)
Browse files Browse the repository at this point in the history
  • Loading branch information
AtofStryker authored Nov 21, 2024
1 parent 15c5761 commit f4aec3e
Show file tree
Hide file tree
Showing 21 changed files with 1,502 additions and 80 deletions.
1 change: 1 addition & 0 deletions cli/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ in this [GitHub issue](https://github.com/cypress-io/cypress/issues/30447). Addr
**Features:**

- Cypress Component Testing now supports `React` version 19. Cypress will allow detected use of the React 19 Release Candidate until React 19 is officially released. Addresses [#29470](https://github.com/cypress-io/cypress/issues/29470).
- Cypress Component Testing now supports `Next.js` version 15. Addresses [#30445](https://github.com/cypress-io/cypress/issues/30445).

**Bugfixes:**

Expand Down
156 changes: 81 additions & 75 deletions npm/webpack-dev-server/cypress/e2e/next.cy.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/// <reference path="../support/e2e.ts" />
import type { ProjectFixtureDir } from '@tooling/system-tests/lib/fixtureDirs'

// keeping this structure for future versions of next.js. Next.js 15 has released but we have not yet added support
const NEXT_PROJECTS: ProjectFixtureDir[] = ['next-14']
// Add to this list to focus on a particular permutation
const ONLY_PROJECTS: ProjectFixtureDir[] = []
Expand Down Expand Up @@ -107,99 +106,106 @@ for (const project of NEXT_PROJECTS) {
})
}

// Since next-14-tsconfig-tailwind does not use the fixture directory we need to write our own test suite
// We want to specifically test typescript files with next-14 as there have been known problems with
// module: bundler and cypress compatibility
describe(`Working with next-14-tsconfig-tailwind`, () => {
beforeEach(() => {
cy.scaffoldProject('next-14-tsconfig-tailwind')
cy.openProject('next-14-tsconfig-tailwind', ['--component'])
cy.startAppServer('component')
})
const NEXT_PROJECTS_TSCONFIG_TAILWIND: ProjectFixtureDir[] = ['next-14-tsconfig-tailwind', 'next-15-tsconfig-tailwind']

it('should mount a passing test', () => {
cy.visitApp()
cy.specsPageIsVisible()
cy.contains('page.cy.tsx').click()
cy.waitForSpecToFinish({ passCount: 1 })
})
for (const project of NEXT_PROJECTS_TSCONFIG_TAILWIND) {
// Since next-tsconfig-tailwind does not use the fixture directory we need to write our own test suite
// We want to specifically test typescript files with next as there have been known problems with
// module: bundler and cypress compatibility
describe(`Working with ${project}`, () => {
beforeEach(() => {
cy.scaffoldProject(project)
cy.openProject(project, ['--component'])
cy.startAppServer('component')
})

it('should mount a passing test', () => {
cy.visitApp()
cy.specsPageIsVisible()
cy.contains('page.cy.tsx').click()
cy.waitForSpecToFinish({ passCount: 1 })
})

it('should live-reload on src changes', () => {
cy.visitApp()
cy.specsPageIsVisible()

it('should live-reload on src changes', () => {
cy.visitApp()
cy.specsPageIsVisible()
cy.contains('page.cy.tsx').click()
cy.waitForSpecToFinish({ passCount: 1 })

cy.contains('page.cy.tsx').click()
cy.waitForSpecToFinish({ passCount: 1 })
cy.withCtx(async (ctx) => {
const indexPath = ctx.path.join('app', 'page.tsx')

cy.withCtx(async (ctx) => {
const indexPath = ctx.path.join('app', 'page.tsx')
await ctx.actions.file.writeFileInProject(
indexPath,
(await ctx.file.readFileInProject(indexPath)).replace('Welcome to', 'Hello from'),
)
})

await ctx.actions.file.writeFileInProject(
indexPath,
(await ctx.file.readFileInProject(indexPath)).replace('Welcome to', 'Hello from'),
)
})
cy.waitForSpecToFinish({ failCount: 1 })
if (project !== 'next-15-tsconfig-tailwind') {
// code frames not fully working with next 15
cy.get('.test-err-code-frame').should('be.visible')
}

cy.waitForSpecToFinish({ failCount: 1 })
cy.get('.test-err-code-frame').should('be.visible')
cy.withCtx(async (ctx) => {
const indexTestPath = ctx.path.join('app', 'page.cy.tsx')

cy.withCtx(async (ctx) => {
const indexTestPath = ctx.path.join('app', 'page.cy.tsx')
await ctx.actions.file.writeFileInProject(
indexTestPath,
(await ctx.file.readFileInProject(indexTestPath)).replace('Welcome to', 'Hello from'),
)
})

await ctx.actions.file.writeFileInProject(
indexTestPath,
(await ctx.file.readFileInProject(indexTestPath)).replace('Welcome to', 'Hello from'),
)
cy.waitForSpecToFinish({ passCount: 1 })
})

cy.waitForSpecToFinish({ passCount: 1 })
})
it('should show compilation errors on src changes', () => {
cy.visitApp()
cy.specsPageIsVisible()

it('should show compilation errors on src changes', () => {
cy.visitApp()
cy.specsPageIsVisible()
cy.contains('page.cy.tsx').click()
cy.waitForSpecToFinish({ passCount: 1 })

cy.contains('page.cy.tsx').click()
cy.waitForSpecToFinish({ passCount: 1 })
// Create compilation error
cy.withCtx(async (ctx) => {
const indexPath = ctx.path.join('app', 'page.tsx')

// Create compilation error
cy.withCtx(async (ctx) => {
const indexPath = ctx.path.join('app', 'page.tsx')
await ctx.actions.file.writeFileInProject(
indexPath,
(await ctx.file.readFileInProject(indexPath)).replace('export', 'expart'),
)
})

await ctx.actions.file.writeFileInProject(
indexPath,
(await ctx.file.readFileInProject(indexPath)).replace('export', 'expart'),
)
// The test should fail and the stack trace should appear in the command log
cy.waitForSpecToFinish({ failCount: 1 })
cy.contains('The following error originated from your test code, not from Cypress.').should('exist')
})

// The test should fail and the stack trace should appear in the command log
cy.waitForSpecToFinish({ failCount: 1 })
cy.contains('The following error originated from your test code, not from Cypress.').should('exist')
})
it('should detect new spec', { retries: 15 }, () => {
cy.visitApp()
cy.specsPageIsVisible()

it('should detect new spec', { retries: 15 }, () => {
cy.visitApp()
cy.specsPageIsVisible()
cy.withCtx(async (ctx) => {
const newTestPath = ctx.path.join('app', 'New.cy.tsx')
const indexTestPath = ctx.path.join('app', 'page.cy.tsx')

cy.withCtx(async (ctx) => {
const newTestPath = ctx.path.join('app', 'New.cy.tsx')
const indexTestPath = ctx.path.join('app', 'page.cy.tsx')
await ctx.actions.file.writeFileInProject(
newTestPath,
await ctx.file.readFileInProject(indexTestPath),
)
})

await ctx.actions.file.writeFileInProject(
newTestPath,
await ctx.file.readFileInProject(indexTestPath),
)
cy.contains('New.cy.tsx').click()
cy.waitForSpecToFinish({ passCount: 1 })
})

cy.contains('New.cy.tsx').click()
cy.waitForSpecToFinish({ passCount: 1 })
})

// Make sure tailwind styles are appearing in the test.
it('should allow import of global styles in support file', { retries: 15 }, () => {
cy.visitApp()
cy.specsPageIsVisible()
cy.contains('page-styles.cy.tsx').click()
cy.waitForSpecToFinish({ passCount: 1 })
// Make sure tailwind styles are appearing in the test.
it('should allow import of global styles in support file', { retries: 15 }, () => {
cy.visitApp()
cy.specsPageIsVisible()
cy.contains('page-styles.cy.tsx').click()
cy.waitForSpecToFinish({ passCount: 1 })
})
})
})
}
2 changes: 1 addition & 1 deletion packages/scaffold-config/src/dependencies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export const WIZARD_DEPENDENCY_NEXT = {
package: 'next',
installer: 'next',
description: 'The React Framework for Production',
minVersion: '^14.0.0',
minVersion: '^14.0.0 || ^15.0.0',
} as const

export const WIZARD_DEPENDENCY_ANGULAR_CLI = {
Expand Down
5 changes: 2 additions & 3 deletions packages/scaffold-config/test/unit/detect.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,13 +131,12 @@ describe('detectFramework', () => {
expect(actual.bundler).to.eq('vite')
})

// keeping array style as to make it easier to support future next versions
;['14.0.0'].forEach((v) => {
;['14.0.0', '15.0.0'].forEach((v) => {
it(`Next.js v${v}`, async () => {
const projectPath = await scaffoldMigrationProject('nextjs-unconfigured')

fakeDepsInNodeModules(projectPath, [
{ dependency: 'react', version: '18.0.0' },
{ dependency: 'react', version: v === '15.0.0' ? '19.0.0-rc.1' : '18.0.0' },
{ dependency: 'next', version: v },
])

Expand Down
2 changes: 1 addition & 1 deletion system-tests/projects/next-14/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "next-latest",
"name": "next-14",
"version": "0.0.0-test",
"scripts": {
"build": "next build",
Expand Down
40 changes: 40 additions & 0 deletions system-tests/projects/next-15-tsconfig-tailwind/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/versions

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# env files (can opt-in for committing if needed)
.env*

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
36 changes: 36 additions & 0 deletions system-tests/projects/next-15-tsconfig-tailwind/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).

## Getting Started

First, run the development server:

```bash
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
```

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.

You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.

This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.

## Learn More

To learn more about Next.js, take a look at the following resources:

- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.

You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!

## Deploy on Vercel

The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.

Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
33 changes: 33 additions & 0 deletions system-tests/projects/next-15-tsconfig-tailwind/app/globals.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

:root {
--foreground-rgb: 0, 0, 0;
--background-start-rgb: 214, 219, 220;
--background-end-rgb: 255, 255, 255;
}

@media (prefers-color-scheme: dark) {
:root {
--foreground-rgb: 255, 255, 255;
--background-start-rgb: 0, 0, 0;
--background-end-rgb: 0, 0, 0;
}
}

body {
color: rgb(var(--foreground-rgb));
background: linear-gradient(
to bottom,
transparent,
rgb(var(--background-end-rgb))
)
rgb(var(--background-start-rgb));
}

@layer utilities {
.text-balance {
text-wrap: balance;
}
}
22 changes: 22 additions & 0 deletions system-tests/projects/next-15-tsconfig-tailwind/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import type { Metadata } from 'next'
import { Inter } from 'next/font/google'
import './globals.css'

const inter = Inter({ subsets: ['latin'] })

export const metadata: Metadata = {
title: 'Create Next App',
description: 'Generated by create next app',
}

export default function RootLayout ({
children,
}: Readonly<{
children: React.ReactNode
}>) {
return (
<html lang="en">
<body className={inter.className}>{children}</body>
</html>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from 'react'
import Home from './page'

describe('<Home />', () => {
it('renders', () => {
cy.mount(<Home />)
cy.contains('h1', 'Welcome to Next.js!')

// verify tailwind classes are applied correctly via import from support file.
cy.get('main').should('have.css', 'background-color', 'rgb(245, 158, 11)')
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React from 'react'
import Home from './page'

describe('<Home />', () => {
it('renders', () => {
cy.mount(<Home />)
cy.contains('h1', 'Welcome to Next.js!')
})
})
7 changes: 7 additions & 0 deletions system-tests/projects/next-15-tsconfig-tailwind/app/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default function Home () {
return (
<main className="bg-amber-500">
<h1> Welcome to Next.js! </h1>
</main>
)
}
Loading

5 comments on commit f4aec3e

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on f4aec3e Nov 21, 2024

Choose a reason for hiding this comment

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

Circle has built the linux x64 version of the Test Runner.

Learn more about this pre-release build at https://on.cypress.io/advanced-installation#Install-pre-release-version

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/13.15.2/linux-x64/release/14.0.0-f4aec3ed4671d415bfd0d5f4e199e53173653a88/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on f4aec3e Nov 21, 2024

Choose a reason for hiding this comment

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

Circle has built the linux arm64 version of the Test Runner.

Learn more about this pre-release build at https://on.cypress.io/advanced-installation#Install-pre-release-version

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/13.15.2/linux-arm64/release/14.0.0-f4aec3ed4671d415bfd0d5f4e199e53173653a88/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on f4aec3e Nov 21, 2024

Choose a reason for hiding this comment

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

Circle has built the win32 x64 version of the Test Runner.

Learn more about this pre-release build at https://on.cypress.io/advanced-installation#Install-pre-release-version

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/13.15.2/win32-x64/release/14.0.0-f4aec3ed4671d415bfd0d5f4e199e53173653a88/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on f4aec3e Nov 21, 2024

Choose a reason for hiding this comment

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

Circle has built the darwin arm64 version of the Test Runner.

Learn more about this pre-release build at https://on.cypress.io/advanced-installation#Install-pre-release-version

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/13.15.2/darwin-arm64/release/14.0.0-f4aec3ed4671d415bfd0d5f4e199e53173653a88/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on f4aec3e Nov 21, 2024

Choose a reason for hiding this comment

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

Circle has built the darwin x64 version of the Test Runner.

Learn more about this pre-release build at https://on.cypress.io/advanced-installation#Install-pre-release-version

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/13.15.2/darwin-x64/release/14.0.0-f4aec3ed4671d415bfd0d5f4e199e53173653a88/cypress.tgz

Please sign in to comment.