test(frontend): Playwright e2e F1 vs backend+fake-pi (hermetic)
Adds a real-browser Playwright e2e of the full F1 disambiguation loop, driven against the real backend + fake binaries (no VPN, no real Pi, no Python). - frontend/e2e/fixtures/fake-tht.mjs: stubs tht CLI (session new/list/show) - frontend/e2e/fixtures/fake-pi.mjs: wraps harness fake-pi-rpc with f1_disambiguation.json - frontend/playwright.config.ts: two webServer entries (backend:8799, frontend:5199) - frontend/e2e/f1.spec.ts: open app → create session → wait for SelectWidget → respond Bug fixes discovered during e2e: - useSessionStream: add addEventListener for named SSE events (backend sends 'event: ui_request' etc.; onmessage only fires for unnamed 'event: message') - FakeEventSource: add no-op addEventListener/removeEventListener stubs - backend SSE route: add CORS headers manually in writeHead() since reply.raw bypasses the @fastify/cors onSend hook - backend: install and register @fastify/cors for all non-SSE routes Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -44,7 +44,16 @@ export function sessionRoutes(app: FastifyInstance, d: { mgr: PiProcessManager;
|
||||
app.get("/sessions/:id/events", (req, reply) => {
|
||||
const id = (req.params as any).id;
|
||||
const rt = d.mgr.get(id);
|
||||
reply.raw.writeHead(200, { "Content-Type": "text/event-stream", "Cache-Control": "no-cache", Connection: "keep-alive" });
|
||||
// Add CORS headers manually: reply.raw.writeHead bypasses Fastify's onSend hooks
|
||||
// (where @fastify/cors injects headers), so we must set them explicitly here.
|
||||
const origin = (req.headers.origin as string | undefined) ?? "*";
|
||||
reply.raw.writeHead(200, {
|
||||
"Content-Type": "text/event-stream",
|
||||
"Cache-Control": "no-cache",
|
||||
Connection: "keep-alive",
|
||||
"Access-Control-Allow-Origin": origin,
|
||||
"Access-Control-Allow-Credentials": "true",
|
||||
});
|
||||
const send = (event: string, data: object) => reply.raw.write(`event: ${event}\ndata: ${JSON.stringify(data)}\n\n`);
|
||||
const off = d.hub.subscribe(id, send, rt?.bridge.pendingWidget() ?? null);
|
||||
req.raw.on("close", off);
|
||||
|
||||
Reference in New Issue
Block a user