chore: perauset customer project
This commit is contained in:
95
e2e/tests/support/hooks.ts
Normal file
95
e2e/tests/support/hooks.ts
Normal file
@@ -0,0 +1,95 @@
|
||||
import { BeforeAll, AfterAll, setDefaultTimeout } from '@cucumber/cucumber'
|
||||
import { spawn, spawnSync, type ChildProcess } from 'child_process'
|
||||
import { mkdirSync, rmSync } from 'fs'
|
||||
import { resolve, dirname } from 'path'
|
||||
import { fileURLToPath } from 'url'
|
||||
import { config } from './config.js'
|
||||
|
||||
setDefaultTimeout(config.timeout)
|
||||
|
||||
let serverProcess: ChildProcess | undefined
|
||||
|
||||
// Provision the isolated e2e db with the real tooling: `pikku db reset` applies
|
||||
// every migration in db/sqlite/ and the db/sqlite-seed.sql seed. PIKKU_SQLITE_DB
|
||||
// points createConfig at this file (see packages/functions/src/config.ts).
|
||||
function provisionDb(projectDir: string, dbFile: string): void {
|
||||
const res = spawnSync('npx', ['pikku', 'db', 'reset'], {
|
||||
cwd: projectDir,
|
||||
env: { ...process.env, PIKKU_SQLITE_DB: dbFile },
|
||||
encoding: 'utf8',
|
||||
})
|
||||
if (res.status !== 0) {
|
||||
throw new Error(
|
||||
`pikku db reset failed (${res.status}):\n${res.stdout ?? ''}\n${res.stderr ?? ''}`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
async function waitForServer(url: string, timeoutMs = 30_000) {
|
||||
const deadline = Date.now() + timeoutMs
|
||||
while (Date.now() < deadline) {
|
||||
try {
|
||||
const res = await fetch(url)
|
||||
if (res.ok || res.status < 500) {
|
||||
console.log(`[backend] ready on ${url}`)
|
||||
return
|
||||
}
|
||||
} catch {
|
||||
// not ready yet
|
||||
}
|
||||
await new Promise((r) => setTimeout(r, 500))
|
||||
}
|
||||
throw new Error(`Backend did not start within ${timeoutMs / 1000}s on ${url}`)
|
||||
}
|
||||
|
||||
BeforeAll(async function () {
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url))
|
||||
const projectDir = resolve(__dirname, '../../..')
|
||||
const port = new URL(config.apiUrl).port
|
||||
|
||||
// Fresh SQLite file per run, provisioned by `pikku db reset`.
|
||||
for (const suffix of ['', '-wal', '-shm']) {
|
||||
rmSync(`${config.dbFile}${suffix}`, { force: true })
|
||||
}
|
||||
mkdirSync(dirname(config.dbFile), { recursive: true })
|
||||
provisionDb(projectDir, config.dbFile)
|
||||
|
||||
const serverEnv: Record<string, string> = {
|
||||
...(process.env as Record<string, string>),
|
||||
PORT: port,
|
||||
E2E_DB_FILE: config.dbFile,
|
||||
BETTER_AUTH_SECRET: 'e2e-test-secret',
|
||||
AUTH_SECRET: 'e2e-test-secret',
|
||||
}
|
||||
|
||||
// Start the isolated SQLite backend.
|
||||
serverProcess = spawn('npx', ['tsx', 'backend/bin/start-e2e.ts'], {
|
||||
cwd: projectDir,
|
||||
env: serverEnv,
|
||||
stdio: 'pipe',
|
||||
detached: true,
|
||||
})
|
||||
|
||||
serverProcess.stderr?.on('data', (d: Buffer) =>
|
||||
process.stderr.write(`[backend] ${d}`)
|
||||
)
|
||||
serverProcess.stdout?.on('data', (d: Buffer) =>
|
||||
process.stdout.write(`[backend] ${d}`)
|
||||
)
|
||||
|
||||
await waitForServer(`${config.apiUrl}/health-check`)
|
||||
// The admin (admin@perauset.org / "test") comes from db/sqlite-seed.sql via
|
||||
// `pikku db reset`. Per-scenario users are created at runtime by the
|
||||
// `a user ... exists` steps (ensureUser).
|
||||
})
|
||||
|
||||
AfterAll(async function () {
|
||||
if (serverProcess?.pid) {
|
||||
try {
|
||||
process.kill(-serverProcess.pid, 'SIGTERM')
|
||||
} catch {
|
||||
// process may already be dead
|
||||
}
|
||||
serverProcess = undefined
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user