rsnext/test/integration/create-next-app/templates-pages.test.ts
JJ Kasper 29c2e89bd1
Break up large test suites (#50458)
This breaks up some of our longest running tests which allows more
parallelizing of the tests. This also moves turbopack tests filtering
back to an allow list as it is running a lot of unrelated tests
currently which isn't ideal. We should only be running against tests
that are explicitly testing turbopack e.g. build tests should not be
duplicated in the turbopack group.

```sh
test/integration/css/test/group-1.test.js: 762.655
test/integration/edge-runtime-module-errors/test/index.test.js: 695.309
test/integration/css/test/group-2.test.js: 671.848
test/integration/i18n-support/test/index.test.js: 518.173
test/integration/scss-modules/test/index.test.js: 451.704
test/integration/css-features/test/index.test.js: 417.318
test/integration/css-modules/test/index.test.js: 403.405
test/integration/eslint/test/index.test.js: 381.563
test/integration/500-page/test/index.test.js: 371.134
test/integration/telemetry/test/index.test.js: 367.691
test/development/acceptance-app/ReactRefreshLogBox.test.ts: 335.878
test/integration/create-next-app/templates.test.ts: 334.01
test/integration/scss/test/group-2.test.js: 327.255
test/integration/scss/test/group-1.test.js: 318.574
test/integration/edge-runtime-configurable-guards/test/index.test.js: 313.834
test/e2e/instrumentation-hook/instrumentation-hook.test.ts: 294.618
test/development/acceptance-app/error-recovery.test.ts: 283.355
test/e2e/app-dir/app/vercel-speed-insights.test.ts: 278.242
test/integration/create-next-app/index.test.ts: 272.442
```
2023-05-28 13:59:41 -07:00

392 lines
9.7 KiB
TypeScript

/* eslint-env jest */
/**
* @fileoverview
*
* This file contains tests for `create-next-app` templates, currently
* JavaScript (default), TypeScript, and appDir.
*/
import path from 'path'
import fs from 'fs-extra'
import {
createNextApp,
projectFilesShouldExist,
shouldBeJavascriptProject,
shouldBeTypescriptProject,
spawnExitPromise,
} from './lib/utils'
import { Span } from 'next/dist/trace'
import { useTempDir } from '../../lib/use-temp-dir'
import {
check,
fetchViaHTTP,
findPort,
killApp,
launchApp,
} from 'next-test-utils'
import resolveFrom from 'resolve-from'
import { createNextInstall } from '../../lib/create-next-install'
import ansiEscapes from 'ansi-escapes'
const startsWithoutError = async (
appDir: string,
modes = ['default', 'turbo'],
usingAppDirectory: boolean = false
) => {
for (const mode of modes) {
appDir = await fs.realpath(appDir)
const appPort = await findPort()
const app = await launchApp(appDir, appPort, {
turbo: mode === 'turbo',
cwd: appDir,
nextBin: resolveFrom(appDir, 'next/dist/bin/next'),
})
try {
const res = await fetchViaHTTP(appPort, '/')
expect(await res.text()).toContain('Get started by editing')
expect(res.status).toBe(200)
if (!usingAppDirectory) {
const apiRes = await fetchViaHTTP(appPort, '/api/hello')
expect(await apiRes.json()).toEqual({ name: 'John Doe' })
expect(apiRes.status).toBe(200)
}
} finally {
await killApp(app)
}
}
}
let testVersion
describe('create-next-app templates', () => {
beforeAll(async () => {
const span = new Span({ name: 'parent' })
testVersion = (
await createNextInstall({ onlyPackages: true, parentSpan: span })
).get('next')
})
it('should prompt user to choose if --ts or --js is not provided', async () => {
await useTempDir(async (cwd) => {
const projectName = 'choose-ts-js'
/**
* Start the create-next-app call.
*/
const childProcess = createNextApp(
[
projectName,
'--no-tailwind',
'--eslint',
'--no-src-dir',
'--no-app',
`--import-alias=@/*`,
],
{
cwd,
},
testVersion
)
/**
* Wait for the prompt to display.
*/
// await new Promise((resolve) => setTimeout(resolve, 1000));
/**
* Bind the exit listener.
*/
await new Promise<void>((resolve, reject) => {
childProcess.on('exit', async (exitCode) => {
expect(exitCode).toBe(0)
/**
* Verify it correctly emitted a TS project by looking for tsconfig.
*/
projectFilesShouldExist({
cwd,
projectName,
files: ['tsconfig.json'],
})
resolve()
})
/**
* Simulate "N" for TypeScript.
*/
childProcess.stdin.write('N\n')
})
})
})
it('should create TS projects with --ts, --typescript', async () => {
await useTempDir(async (cwd) => {
const projectName = 'typescript-test'
const childProcess = createNextApp(
[
projectName,
'--ts',
'--no-tailwind',
'--eslint',
'--no-src-dir',
'--no-app',
`--import-alias=@/*`,
],
{
cwd,
},
testVersion
)
const exitCode = await spawnExitPromise(childProcess)
expect(exitCode).toBe(0)
shouldBeTypescriptProject({ cwd, projectName, template: 'default' })
await startsWithoutError(path.join(cwd, projectName))
})
})
it('should create TS projects with --ts, --typescript --src-dir', async () => {
await useTempDir(async (cwd) => {
const projectName = 'typescript-test'
const childProcess = createNextApp(
[
projectName,
'--ts',
'--no-tailwind',
'--eslint',
'--src-dir',
'--no-app',
`--import-alias=@/*`,
],
{
cwd,
},
testVersion
)
const exitCode = await spawnExitPromise(childProcess)
expect(exitCode).toBe(0)
shouldBeTypescriptProject({
cwd,
projectName,
template: 'default',
srcDir: true,
})
await startsWithoutError(path.join(cwd, projectName))
})
})
it('should create JS projects with --js, --javascript', async () => {
await useTempDir(async (cwd) => {
const projectName = 'javascript-test'
const childProcess = createNextApp(
[
projectName,
'--js',
'--no-tailwind',
'--eslint',
'--no-src-dir',
'--no-app',
`--import-alias=@/*`,
],
{
cwd,
},
testVersion
)
const exitCode = await spawnExitPromise(childProcess)
expect(exitCode).toBe(0)
shouldBeJavascriptProject({ cwd, projectName, template: 'default' })
await startsWithoutError(path.join(cwd, projectName), [
'default',
'turbo',
])
})
})
it('should create JS projects with --js, --javascript --src-dir', async () => {
await useTempDir(async (cwd) => {
const projectName = 'javascript-test'
const childProcess = createNextApp(
[
projectName,
'--js',
'--no-tailwind',
'--eslint',
'--src-dir',
'--no-app',
`--import-alias=@/*`,
],
{
cwd,
},
testVersion
)
const exitCode = await spawnExitPromise(childProcess)
expect(exitCode).toBe(0)
shouldBeJavascriptProject({
cwd,
projectName,
template: 'default',
srcDir: true,
})
await startsWithoutError(path.join(cwd, projectName), [
'default',
'turbo',
])
})
})
it('should prompt user to choose if --import-alias is not provided', async () => {
await useTempDir(async (cwd) => {
const projectName = 'choose-import-alias'
/**
* Start the create-next-app call.
*/
const childProcess = createNextApp(
[
projectName,
'--ts',
'--no-tailwind',
'--eslint',
'--no-src-dir',
'--no-app',
],
{
cwd,
},
testVersion
)
/**
* Bind the exit listener.
*/
await new Promise<void>(async (resolve) => {
childProcess.on('exit', async (exitCode) => {
expect(exitCode).toBe(0)
resolve()
})
let output = ''
childProcess.stdout.on('data', (data) => {
output += data
process.stdout.write(data)
})
childProcess.stdin.write(ansiEscapes.cursorForward() + '\n')
await check(() => output, /What import alias would you like configured/)
childProcess.stdin.write('@/something/*\n')
})
/**
* Verify it correctly emitted a TS project by looking for tsconfig.
*/
const tsConfig = require(path.join(cwd, projectName, 'tsconfig.json'))
expect(tsConfig.compilerOptions.paths).toMatchInlineSnapshot(`
Object {
"@/something/*": Array [
"./*",
],
}
`)
})
})
it('should work with --tailwind and --src together', async () => {
await useTempDir(async (cwd) => {
const projectName = 'tailwind-js-src'
/**
* Start the create-next-app call.
*/
const childProcess = createNextApp(
[
projectName,
'--js',
'--no-eslint',
'--tailwind',
'--src-dir',
'--no-app',
`--import-alias=@/*`,
],
{
cwd,
},
testVersion
)
/**
* Wait for the prompt to display.
*/
// await new Promise((resolve) => setTimeout(resolve, 1000));
/**
* Bind the exit listener.
*/
await new Promise<void>((resolve, reject) => {
childProcess.on('exit', async (exitCode) => {
expect(exitCode).toBe(0)
/**
* Verify it correctly emitted a Tailwind project by looking for tailwind.config.js.
*/
projectFilesShouldExist({
cwd,
projectName,
files: ['tailwind.config.js'],
})
resolve()
})
/**
* Simulate "N" for Tailwind.
*/
childProcess.stdin.write('N\n')
})
})
})
it('should prompt user to choose if --tailwind or --no-tailwind is not provided', async () => {
await useTempDir(async (cwd) => {
const projectName = 'choose-tailwind'
/**
* Start the create-next-app call.
*/
const childProcess = createNextApp(
[
projectName,
'--js',
'--eslint',
'--no-src-dir',
'--no-app',
`--import-alias=@/*`,
],
{
cwd,
},
testVersion
)
/**
* Wait for the prompt to display.
*/
// await new Promise((resolve) => setTimeout(resolve, 1000));
/**
* Bind the exit listener.
*/
await new Promise<void>((resolve, reject) => {
childProcess.on('exit', async (exitCode) => {
expect(exitCode).toBe(0)
/**
* Verify it correctly emitted a Tailwind project by looking for tailwind.config.js.
*/
projectFilesShouldExist({
cwd,
projectName,
files: ['tailwind.config.js'],
})
resolve()
})
/**
* Simulate "N" for Tailwind.
*/
childProcess.stdin.write('N\n')
})
})
})
})