test(server): vite server restart flow (#12777)

This commit is contained in:
sun0day 2023-04-25 23:53:04 +08:00 committed by GitHub
parent 061e48b0a3
commit ef7b720432
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 54 additions and 11 deletions

View File

@ -1,6 +1,6 @@
import { expect, test } from 'vitest'
import { port } from './serve'
import { page } from '~utils'
import { port, streams } from './serve'
import { editFile, page, withRetry } from '~utils'
test('cli should work', async () => {
// this test uses a custom serve implementation, so regular helpers for browserLogs and goto don't work
@ -12,9 +12,22 @@ test('cli should work', async () => {
try {
page.on('console', onConsole)
await page.goto(`http://localhost:${port}/`)
expect(await page.textContent('.app')).toBe('vite cli works!')
expect(logs.some((msg) => msg.match('vite cli works!'))).toBe(true)
} finally {
page.off('console', onConsole)
}
})
test('should restart', async () => {
editFile('./vite.config.js', (content) => content)
await withRetry(async () => {
expect(streams.server.out).toEqual(
expect.arrayContaining([expect.stringMatching('server restarted')]),
)
expect(streams.server.out).not.toEqual(
expect.arrayContaining([expect.stringMatching('error')]),
)
})
})

View File

@ -13,13 +13,16 @@ import {
} from '~utils'
export const port = ports.cli
export const streams = {} as {
build: { out: string[]; err: string[] }
server: { out: string[]; err: string[] }
}
export async function serve() {
// collect stdout and stderr streams from child processes here to avoid interfering with regular vitest output
const streams = {
Object.assign(streams, {
build: { out: [], err: [] },
server: { out: [], err: [] },
}
})
// helpers to collect streams
const collectStreams = (name, process) => {
process.stdout.on('data', (d) => streams[name].out.push(d.toString()))

View File

@ -3,15 +3,21 @@
import path from 'node:path'
import kill from 'kill-port'
import { hmrPorts, ports, rootDir } from '~utils'
import { createInMemoryLogger, hmrPorts, ports, rootDir } from '~utils'
export const port = ports.ssr
export const serverLogs = []
export async function serve(): Promise<{ close(): Promise<void> }> {
await kill(port)
const { createServer } = await import(path.resolve(rootDir, 'server.js'))
const { app, vite } = await createServer(rootDir, hmrPorts.ssr)
const { app, vite } = await createServer(
rootDir,
hmrPorts.ssr,
createInMemoryLogger(serverLogs),
)
return new Promise((resolve, reject) => {
try {

View File

@ -1,6 +1,6 @@
import { expect, test } from 'vitest'
import { port } from './serve'
import { page } from '~utils'
import { port, serverLogs } from './serve'
import { editFile, page, withRetry } from '~utils'
const url = `http://localhost:${port}`
@ -17,3 +17,15 @@ test(`deadlock doesn't happen`, async () => {
expect(await page.textContent('.forked-deadlock')).toMatch('rendered')
})
test('should restart ssr', async () => {
editFile('./vite.config.ts', (content) => content)
await withRetry(async () => {
expect(serverLogs).toEqual(
expect.arrayContaining([expect.stringMatching('server restarted')]),
)
expect(serverLogs).not.toEqual(
expect.arrayContaining([expect.stringMatching('error')]),
)
})
})

View File

@ -6,7 +6,11 @@ import express from 'express'
const __dirname = path.dirname(fileURLToPath(import.meta.url))
const isTest = process.env.VITEST
export async function createServer(root = process.cwd(), hmrPort) {
export async function createServer(
root = process.cwd(),
hmrPort,
customLogger,
) {
const resolve = (p) => path.resolve(__dirname, p)
const app = express()
@ -32,6 +36,7 @@ export async function createServer(root = process.cwd(), hmrPort) {
},
},
appType: 'custom',
customLogger,
})
// use vite's connect instance as middleware
app.use(vite.middlewares)

View File

@ -0,0 +1,4 @@
import { defineConfig } from 'vite'
// in order to trigger ssr server restart
export default defineConfig({})

View File

@ -312,7 +312,7 @@ export async function notifyRebuildComplete(
return watcher.off('event', callback)
}
function createInMemoryLogger(logs: string[]): Logger {
export function createInMemoryLogger(logs: string[]): Logger {
const loggedErrors = new WeakSet<Error | RollupError>()
const warnedMessages = new Set<string>()