/* eslint-disable no-console -- CLI tool: stdout/stderr are the user interface. */ /** * Sentry smoke-test driver for apps/web. * * Hits the test routes registered in apps/web/app/routes/__test.* and * verifies that the HTTP responses look right. Use against a deployed * staging environment after enabling SENTRY_TEST_ROUTES=true. * * Usage: * pnpm exec tsx apps/web/scripts/smoke-sentry.ts https://app.staging.example * * Exit codes: * 0 — all probes returned the expected status code * 1 — at least one probe failed; details are printed to stderr * * @see docs/improvement-plan/02-observability/sentry-wiring-web.md (Step 11) */ interface Probe { path: string; note: string; expectedStatus: number | number[]; } const probes: Probe[] = [ { path: "/__test/client-throw", note: "Client-side throw smoke route (loader returns 200, component throws on render)", expectedStatus: 200, }, ]; async function runProbe(baseUrl: string, probe: Probe): Promise<{ probe: Probe; ok: boolean; status: number; bodySnippet: string }> { const url = new URL(probe.path, baseUrl).toString(); const response = await fetch(url, { redirect: "manual" }); const body = await response.text(); const expectedStatuses = Array.isArray(probe.expectedStatus) ? probe.expectedStatus : [probe.expectedStatus]; return { probe, ok: expectedStatuses.includes(response.status), status: response.status, bodySnippet: body.slice(0, 200), }; } export async function runSmoke(baseUrl: string): Promise { if (!baseUrl) { console.error("usage: smoke-sentry.ts "); return 1; } console.log(`[smoke-sentry] target=${baseUrl}`); const results = await Promise.all(probes.map((p) => runProbe(baseUrl, p))); let failures = 0; for (const r of results) { if (r.ok) { console.log(`[ok] ${r.probe.path} → ${r.status} (${r.probe.note})`); } else { failures += 1; console.error(`[fail] ${r.probe.path} → ${r.status} expected=${r.probe.expectedStatus} body=${r.bodySnippet}`); } } if (failures > 0) { console.error(`[smoke-sentry] ${failures} probe(s) failed`); return 1; } console.log("[smoke-sentry] all probes passed"); console.log("[smoke-sentry] verify in Sentry UI: a client-throw event with stack-trace pointing to __test.client-throw.tsx"); return 0; } const isMain = typeof process !== "undefined" && Array.isArray(process.argv) && process.argv[1] && import.meta.url === `file://${process.argv[1]}`; if (isMain) { const baseUrl = process.argv[2] ?? process.env.SENTRY_SMOKE_BASE_URL ?? ""; runSmoke(baseUrl).then((code) => process.exit(code)); }