import { describe, test, beforeAll, afterAll, expect } from 'vitest'; import { getWebsiteRouteContracts, RouteContract } from '../../../shared/website/RouteContractSpec'; import { WebsiteServerHarness } from '../../harness/WebsiteServerHarness'; import { ApiServerHarness } from '../../harness/ApiServerHarness'; import { HttpDiagnostics } from '../../../shared/website/HttpDiagnostics'; const WEBSITE_BASE_URL = process.env.WEBSITE_BASE_URL || 'http://localhost:3005'; const API_BASE_URL = process.env.API_BASE_URL || 'http://localhost:3006'; // Ensure WebsiteRouteManager uses the same persistence mode as the API harness process.env.GRIDPILOT_API_PERSISTENCE = 'inmemory'; describe('Website SSR Integration', () => { let websiteHarness: WebsiteServerHarness | null = null; let apiHarness: ApiServerHarness | null = null; const contracts = getWebsiteRouteContracts(); beforeAll(async () => { // 1. Start API console.log(`[WebsiteSSR] Starting API harness on ${API_BASE_URL}...`); apiHarness = new ApiServerHarness({ port: parseInt(new URL(API_BASE_URL).port) || 3006, }); await apiHarness.start(); console.log(`[WebsiteSSR] API Harness started.`); // 2. Start Website console.log(`[WebsiteSSR] Starting website harness on ${WEBSITE_BASE_URL}...`); websiteHarness = new WebsiteServerHarness({ port: parseInt(new URL(WEBSITE_BASE_URL).port) || 3005, env: { PORT: '3005', API_BASE_URL: API_BASE_URL, NEXT_PUBLIC_API_BASE_URL: API_BASE_URL, NODE_ENV: 'test', }, }); await websiteHarness.start(); console.log(`[WebsiteSSR] Website Harness started.`); }, 180000); afterAll(async () => { if (websiteHarness) { await websiteHarness.stop(); } if (apiHarness) { await apiHarness.stop(); } }); test.each(contracts)('SSR for $path ($accessLevel)', async (contract: RouteContract) => { const url = `${WEBSITE_BASE_URL}${contract.path}`; const response = await fetch(url, { method: 'GET', redirect: 'manual', }); const status = response.status; const location = response.headers.get('location'); const html = await response.text(); if (status === 500) { console.error(`[WebsiteSSR] 500 Error at ${contract.path}. HTML:`, html.substring(0, 10000)); const errorMatch = html.match(/]*>([\s\S]*?)<\/pre>/); if (errorMatch) { console.error(`[WebsiteSSR] Error details from HTML:`, errorMatch[1]); } const nextDataMatch = html.match(/