tailwindcss/integrations/postcss/next.test.ts
Philipp Spiess e10b786437
Add Next.js integration test (#14163)
Using the [new integration test
setup](https://github.com/tailwindlabs/tailwindcss/pull/14089), this PR
adds a test for a V4 Next.js setup using the Postcss plugin. It's
testing both a full build and the dev mode (non-turbo for now).

Because of webpack, tests are quite slow which is worrisome since we
probably need to add many more integrations in the future. One idea I
have is that we separate tests in two buckets: _essential_ tests that
run often and are fast and advanced suites that we only run on CI via
custom, non-blocking, jobs.

---------

Co-authored-by: Jordan Pittman <jordan@cryptica.me>
2024-08-16 15:45:52 +02:00

154 lines
3.9 KiB
TypeScript

import { expect } from 'vitest'
import { candidate, css, fetchStylesFromIndex, js, json, retryAssertion, test } from '../utils'
test(
'production build',
{
fs: {
'package.json': json`
{
"dependencies": {
"react": "^18",
"react-dom": "^18",
"next": "^14"
},
"devDependencies": {
"@tailwindcss/postcss": "workspace:^",
"tailwindcss": "workspace:^"
}
}
`,
'postcss.config.mjs': js`
/** @type {import('postcss-load-config').Config} */
const config = {
plugins: {
'@tailwindcss/postcss': {},
},
}
export default config
`,
'next.config.mjs': js`
/** @type {import('next').NextConfig} */
const nextConfig = {}
export default nextConfig
`,
'app/layout.js': js`
import './globals.css'
export default function RootLayout({ children }) {
return (
<html>
<body>{children}</body>
</html>
)
}
`,
'app/page.js': js`
export default function Page() {
return <h1 className="text-3xl font-bold underline">Hello, Next.js!</h1>
}
`,
'app/globals.css': css`
@import 'tailwindcss/theme' theme(reference);
@import 'tailwindcss/utilities';
`,
},
},
async ({ fs, exec }) => {
await exec('pnpm next build')
let files = await fs.glob('.next/static/css/**/*.css')
expect(files).toHaveLength(1)
let [filename] = files[0]
await fs.expectFileToContain(filename, [
candidate`underline`,
candidate`font-bold`,
candidate`text-3xl`,
])
},
)
;['turbo', 'webpack'].forEach((bundler) => {
test(
`dev mode (${bundler})`,
{
fs: {
'package.json': json`
{
"dependencies": {
"react": "^18",
"react-dom": "^18",
"next": "^14"
},
"devDependencies": {
"@tailwindcss/postcss": "workspace:^",
"tailwindcss": "workspace:^"
}
}
`,
'postcss.config.mjs': js`
/** @type {import('postcss-load-config').Config} */
const config = {
plugins: {
'@tailwindcss/postcss': {},
},
}
export default config
`,
'next.config.mjs': js`
/** @type {import('next').NextConfig} */
const nextConfig = {}
export default nextConfig
`,
'app/layout.js': js`
import './globals.css'
export default function RootLayout({ children }) {
return (
<html>
<body>{children}</body>
</html>
)
}
`,
'app/page.js': js`
export default function Page() {
return <h1 className="underline">Hello, Next.js!</h1>
}
`,
'app/globals.css': css`
@import 'tailwindcss/theme' theme(reference);
@import 'tailwindcss/utilities';
`,
},
},
async ({ fs, spawn, getFreePort }) => {
let port = await getFreePort()
await spawn(`pnpm next dev ${bundler === 'turbo' ? '--turbo' : ''} --port ${port}`)
await retryAssertion(async () => {
let css = await fetchStylesFromIndex(port)
expect(css).toContain(candidate`underline`)
})
await fs.write(
'app/page.js',
js`
export default function Page() {
return <h1 className="underline text-red-500">Hello, Next.js!</h1>
}
`,
)
await retryAssertion(async () => {
let css = await fetchStylesFromIndex(port)
expect(css).toContain(candidate`underline`)
expect(css).toContain(candidate`text-red-500`)
})
},
)
})