"use strict"; // 说明: // - 这是一条最小首页入口 smoke,不验证完整业务流。 // - 它只验证 3000 主站入口链路是否可达,并明确 3104 不是首页可进入的前置条件。 // - 未登录场景允许 "/" 返回 30x 到 "/auth",也允许直接返回 HTML。 const BASE_URL = (process.env.MNOTE_UI_BASE_URL || "http://127.0.0.1:3000").replace(/\/+$/, ""); const TIMEOUT_MS = Number(process.env.MNOTE_SMOKE_TIMEOUT_MS || 8000); function assert(condition, message) { if (!condition) { throw new Error(message); } } async function fetchWithTimeout(url, init = {}) { const controller = new AbortController(); const timer = setTimeout(() => controller.abort(new Error(`请求超时: ${url}`)), TIMEOUT_MS); try { return await fetch(url, { redirect: "manual", cache: "no-store", ...init, signal: controller.signal, }); } finally { clearTimeout(timer); } } async function readSnippet(response) { const text = await response.text().catch(() => ""); return text.slice(0, 200); } async function validateAuthEntry() { const response = await fetchWithTimeout(`${BASE_URL}/auth`, { method: "GET" }); const contentType = response.headers.get("content-type") || ""; const snippet = await readSnippet(response); assert(response.ok, `/auth 请求失败: ${response.status} ${snippet}`); assert( contentType.includes("text/html"), `/auth 返回了非 HTML 内容: ${contentType || ""} ${snippet}`, ); return { status: response.status, contentType, }; } async function validateRootEntry() { const response = await fetchWithTimeout(`${BASE_URL}/`, { method: "GET" }); const location = response.headers.get("location"); const contentType = response.headers.get("content-type") || ""; const snippet = await readSnippet(response); const isRedirectToAllowedTarget = response.status >= 300 && response.status < 400 && typeof location === "string" && (location.includes("/auth") || location.includes("/documents/")); const isHtmlOk = response.ok && contentType.includes("text/html"); assert( isRedirectToAllowedTarget || isHtmlOk, `/ 返回了不符合预期的结果: status=${response.status} location=${location || ""} contentType=${contentType || ""} snippet=${snippet}`, ); return { status: response.status, location, contentType, }; } async function main() { const authEntry = await validateAuthEntry(); const rootEntry = await validateRootEntry(); console.log( JSON.stringify( { ok: true, baseUrl: BASE_URL, authEntry, rootEntry, }, null, 2, ), ); } main().catch((error) => { console.error(error instanceof Error ? error.stack || error.message : String(error)); process.exit(1); });