mirror of
https://github.com/hanzoai/next.js.git
synced 2026-10-30 14:46:38 +00:00
This functionality was added late in #87258 but was broken as we needed to pass this along to the Rust side. We'd also need to be able to write to arbitrary absolute paths there, so let's punt on it. Test Plan: e2e tests
139 lines
3.8 KiB
TypeScript
139 lines
3.8 KiB
TypeScript
import { nextTestSetup } from 'e2e-utils'
|
|
import { runNextCommand, shouldUseTurbopack } from 'next-test-utils'
|
|
import path from 'node:path'
|
|
import { ChildProcess, spawn } from 'node:child_process'
|
|
import { existsSync, readFileSync } from 'node:fs'
|
|
|
|
describe('next experimental-analyze', () => {
|
|
if (!shouldUseTurbopack()) {
|
|
// Test suites require at least one test
|
|
it('skips in non-Turbopack tests', () => {})
|
|
return
|
|
}
|
|
|
|
const { next, skipped } = nextTestSetup({
|
|
files: __dirname,
|
|
skipStart: true,
|
|
skipDeployment: true,
|
|
})
|
|
|
|
if (skipped) {
|
|
// Test suites require at least one test
|
|
it('is skipped', () => {})
|
|
return
|
|
}
|
|
|
|
it('runs successfully without errors', async () => {
|
|
const nextDir = path.dirname(require.resolve('next/package'))
|
|
const nextBin = path.join(nextDir, 'dist/bin/next')
|
|
|
|
const serveProcess = spawn(
|
|
'node',
|
|
[nextBin, 'experimental-analyze', '--port', '0'],
|
|
{
|
|
cwd: next.testDir,
|
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
}
|
|
)
|
|
|
|
try {
|
|
const url = await waitForServer(serveProcess)
|
|
const response = await fetch(url)
|
|
expect(response.status).toBe(200)
|
|
expect(await response.text()).toContain(
|
|
'<title>Next.js Bundle Analyzer</title>'
|
|
)
|
|
} finally {
|
|
serveProcess.kill()
|
|
}
|
|
})
|
|
;['-o', '--output'].forEach((flag) => {
|
|
describe(`with ${flag} flag`, () => {
|
|
it('writes output to .next/diagnostics/analyze path', async () => {
|
|
const defaultOutputPath = path.join(
|
|
next.testDir,
|
|
'.next/diagnostics/analyze'
|
|
)
|
|
|
|
const { code, stderr, stdout } = await runNextCommand(
|
|
['experimental-analyze', flag],
|
|
{
|
|
cwd: next.testDir,
|
|
stderr: true,
|
|
stdout: true,
|
|
}
|
|
)
|
|
|
|
expect(code).toBe(0)
|
|
expect(stderr).not.toContain('Error')
|
|
expect(stdout).toContain('.next/diagnostics/analyze')
|
|
|
|
expect(existsSync(defaultOutputPath)).toBe(true)
|
|
for (const file of [
|
|
'index.html',
|
|
'data/routes.json',
|
|
'data/modules.data',
|
|
'data/analyze.data',
|
|
]) {
|
|
expect(existsSync(path.join(defaultOutputPath, file))).toBe(true)
|
|
}
|
|
|
|
const routesJson = readFileSync(
|
|
path.join(defaultOutputPath, 'data', 'routes.json'),
|
|
'utf-8'
|
|
)
|
|
const routes = JSON.parse(routesJson)
|
|
expect(routes).toEqual(['/', '/_not-found'])
|
|
})
|
|
})
|
|
})
|
|
})
|
|
|
|
function waitForServer(process: ChildProcess, timeoutMs: number = 30000) {
|
|
const serverUrlPromise = new Promise<string>((resolve, reject) => {
|
|
const timeout = setTimeout(() => {
|
|
process.stdout.off('data', onStdout)
|
|
process.off('error', onError)
|
|
process.off('exit', onExit)
|
|
reject(new Error('Server did not start within timeout'))
|
|
}, timeoutMs)
|
|
|
|
function onStdout(data: Buffer) {
|
|
const urlMatch = data.toString().match(/http:\/\/[^\s]+/)
|
|
if (urlMatch) {
|
|
clearTimeout(timeout)
|
|
process.stdout.off('data', onStdout)
|
|
process.off('error', onError)
|
|
process.off('exit', onExit)
|
|
resolve(urlMatch[0])
|
|
}
|
|
}
|
|
|
|
function onError(error: Error) {
|
|
clearTimeout(timeout)
|
|
process.stdout.off('data', onStdout)
|
|
process.off('error', onError)
|
|
process.off('exit', onExit)
|
|
reject(error)
|
|
}
|
|
|
|
function onExit(code: number) {
|
|
clearTimeout(timeout)
|
|
process.stdout.off('data', onStdout)
|
|
process.off('error', onError)
|
|
process.off('exit', onExit)
|
|
reject(
|
|
new Error(
|
|
`Server process exited with code ${code} before URL was emitted`
|
|
)
|
|
)
|
|
}
|
|
|
|
process.stdout.on('data', onStdout)
|
|
process.on('error', onError)
|
|
process.on('exit', onExit)
|
|
})
|
|
|
|
return serverUrlPromise
|
|
}
|