Files
stock-manager/tests/e2e/support/e2e-server.ts
T
2026-06-11 04:56:01 +02:00

111 lines
2.7 KiB
TypeScript

import { type ChildProcess, execFileSync, spawn } from "node:child_process"
import process from "node:process"
import {
PostgreSqlContainer,
type StartedPostgreSqlContainer,
} from "@testcontainers/postgresql"
const port = process.env.E2E_PORT ?? "3100"
const host = "127.0.0.1"
const baseUrl = `http://${host}:${port}`
let container: StartedPostgreSqlContainer | undefined
let nextProcess: ChildProcess | undefined
let shuttingDown = false
async function cleanup() {
if (shuttingDown) return
shuttingDown = true
if (nextProcess && !nextProcess.killed) {
nextProcess.kill("SIGTERM")
}
await container?.stop()
container = undefined
}
async function main() {
container = await new PostgreSqlContainer("postgres:18-alpine")
.withDatabase("stock_manager_e2e")
.withUsername("e2e")
.withPassword("e2e")
.start()
const databaseUrl = container.getConnectionUri()
const env = {
...process.env,
DATABASE_URL: databaseUrl,
AUTH_SECRET: process.env.AUTH_SECRET ?? "e2e-auth-secret",
AUTH_URL: baseUrl,
NEXTAUTH_URL: baseUrl,
ADMIN_BOOTSTRAP_ENABLED: "true",
ADMIN_USERNAME: "admin",
ADMIN_EMAIL: "admin@example.test",
ADMIN_NAME: "E2E Admin",
ADMIN_PASSWORD: "admin-password",
}
process.env.DATABASE_URL = databaseUrl
process.env.AUTH_SECRET = env.AUTH_SECRET
process.env.AUTH_URL = baseUrl
process.env.NEXTAUTH_URL = baseUrl
process.env.ADMIN_BOOTSTRAP_ENABLED = "true"
process.env.ADMIN_USERNAME = "admin"
process.env.ADMIN_EMAIL = "admin@example.test"
process.env.ADMIN_NAME = "E2E Admin"
process.env.ADMIN_PASSWORD = "admin-password"
try {
execFileSync("bunx", ["prisma", "migrate", "deploy"], {
env,
stdio: "inherit",
})
const prismaModule = await import("@/lib/prisma")
const bootstrapModule = await import("../../../prisma/bootstrap-admin")
await bootstrapModule.bootstrapAdmin(prismaModule.prisma)
await prismaModule.prisma.$disconnect()
} catch (error) {
await cleanup()
throw error
}
const startedNextProcess = spawn(
"bunx",
["next", "dev", "--webpack", "--hostname", host, "--port", port],
{
env,
stdio: "inherit",
},
)
nextProcess = startedNextProcess
startedNextProcess.on("exit", async (code, signal) => {
const wasShuttingDown = shuttingDown
await cleanup()
if (!wasShuttingDown && code !== 0) {
console.error(`Next dev server exited with code ${code} signal ${signal}`)
process.exit(code ?? 1)
}
})
}
process.on("SIGTERM", async () => {
await cleanup()
process.exit(0)
})
process.on("SIGINT", async () => {
await cleanup()
process.exit(0)
})
main().catch(async (error) => {
console.error(error)
await cleanup()
process.exit(1)
})