66 lines
3.5 KiB
JavaScript
66 lines
3.5 KiB
JavaScript
import {writeFile,unlink} from 'node:fs/promises';
|
|
import sharp from 'sharp';
|
|
import { spawn } from "node:child_process";
|
|
import assert from "node:assert/strict";
|
|
import { setTimeout } from "node:timers/promises";
|
|
import { createServer } from "node:net";
|
|
import { once } from "node:events";
|
|
|
|
async function availablePort() {
|
|
const server = createServer();
|
|
server.listen(0, "127.0.0.1");
|
|
await once(server, "listening");
|
|
const port = server.address().port;
|
|
await new Promise((resolve, reject) => server.close(error => error ? reject(error) : resolve()));
|
|
return String(port);
|
|
}
|
|
|
|
const port = process.env.SMOKE_PORT || await availablePort();
|
|
const release = "smoke-test";
|
|
const previewFixture='.next/standalone/public/__smoke-preview.png';
|
|
await writeFile(previewFixture,await sharp({create:{width:48,height:48,channels:3,background:'#eee'}}).png().toBuffer());
|
|
const child = spawn(process.execPath, [".next/standalone/server.js"], {
|
|
// This loopback-only child checks retained resources without production credentials.
|
|
// Production keeps failing closed; the bypass requires both explicit test settings.
|
|
env: { ...process.env, AUTH_CONFIG_FILE: "", AUTH_DISABLED_FOR_TESTS: "true", PORT: port, HOSTNAME: "127.0.0.1", RELEASE_SHA: release },
|
|
stdio: "inherit",
|
|
});
|
|
try {
|
|
let ready = false;
|
|
for (let i = 0; i < 40; i++) {
|
|
if (child.exitCode !== null) throw new Error(`Server exited: ${child.exitCode}`);
|
|
try {
|
|
const response = await fetch(`http://127.0.0.1:${port}/api/health`);
|
|
assert.equal(response.status, 200);
|
|
assert.deepEqual(await response.json(), { status: "ok", service: "prompt", release });
|
|
ready = true;
|
|
break;
|
|
} catch { await setTimeout(500); }
|
|
}
|
|
assert.ok(ready, "Standalone production server must be healthy");
|
|
const response = await fetch(`http://127.0.0.1:${port}/api/health`, { method: "POST" });
|
|
assert.equal(response.status, 405);
|
|
const indexResponse=await fetch(`http://127.0.0.1:${port}/api/wiki-index`);
|
|
assert.equal(indexResponse.status,200);
|
|
const indexText=await indexResponse.text();
|
|
const id=indexText.match(/\/explore\/([a-f0-9]{24})/)?.[1];assert.ok(id);
|
|
const agent=await fetch(`http://127.0.0.1:${port}/explore/${id}?agent_mode=True`);
|
|
assert.equal(agent.status,200);assert.match(agent.headers.get('content-type'),/text\/plain/);const agentText=await agent.text();assert.match(agentText,/^# /);assert.doesNotMatch(agentText,/^\s*(?:<!doctype html|<html)/i);
|
|
const preview=await fetch(`http://127.0.0.1:${port}/api/preview?source=${encodeURIComponent('/__smoke-preview.png')}&width=480`);
|
|
assert.equal(preview.status,200);assert.match(preview.headers.get('content-type'),/image\/webp/);assert.ok((await preview.arrayBuffer()).byteLength<=100000);
|
|
const home=await fetch(`http://127.0.0.1:${port}/`).then(r=>r.text());
|
|
for(const href of ['/graphic','/infinite_canvas','/account?next=/workspace'])assert.ok(home.includes(`href="${href}"`),href);
|
|
for(const [legacy,canonical] of [['/studio/graphic','/graphic'],['/studio/infinite_canvas','/infinite_canvas']]){
|
|
const redirect=await fetch(`http://127.0.0.1:${port}${legacy}`,{redirect:'manual'});
|
|
assert.equal(redirect.status,308);assert.equal(redirect.headers.get('location'),canonical);
|
|
}
|
|
console.log("Production smoke test passed, including landing entry points and canonical redirects");
|
|
} finally {
|
|
await unlink(previewFixture);
|
|
if (child.exitCode === null && child.signalCode === null) {
|
|
const exited = once(child, "exit");
|
|
child.kill("SIGTERM");
|
|
await exited;
|
|
}
|
|
}
|