Просмотр исходного кода

test(e2e): fail fast when dev services are unavailable

YY968XX 1 месяц назад
Родитель
Сommit
42a563bc44
2 измененных файлов с 64 добавлено и 0 удалено
  1. 3 0
      Web/tests/e2e/global-setup.ts
  2. 61 0
      Web/tests/e2e/utils/health-check.ts

+ 3 - 0
Web/tests/e2e/global-setup.ts

@@ -1,6 +1,9 @@
 import { chromium } from '@playwright/test';
 import { ensureStorageState } from './fixtures/auth';
+import { assertServicesHealthy } from './utils/health-check';
 
 export default async function globalSetup(): Promise<void> {
+  // HEALTH-1:dev 服务掉线时 fail-fast,避免被误判为业务回归。
+  await assertServicesHealthy();
   await ensureStorageState(() => chromium.launch());
 }

+ 61 - 0
Web/tests/e2e/utils/health-check.ts

@@ -0,0 +1,61 @@
+/**
+ * 本地 dev 服务健康预热:在 e2e 运行前 fail-fast,
+ * 避免服务掉线时把 page.goto('/') / authedPage 失败误判为业务回归。
+ *
+ * 边界:
+ *  - 仅检查可达性(Connection)+ 状态码 < 500;不校验业务响应
+ *  - 不引入新依赖(Node 18+ 内置 fetch)
+ *  - 不自动启动/重启服务;仅指明修复路径
+ *  - 不访问数据库
+ */
+
+const WEB_URL = process.env.AIDOP_E2E_WEB_HEALTH_URL ?? 'http://localhost:8888/';
+const API_URL = process.env.AIDOP_E2E_API_HEALTH_URL ?? 'http://localhost:5005/';
+const TIMEOUT_MS = Number(process.env.AIDOP_E2E_HEALTH_TIMEOUT_MS ?? 5000);
+const RESTART_HINT = 'bash /home/yy968/work/New9S/restart_aidop.sh';
+
+type ProbeOutcome =
+  | { ok: true; status: number }
+  | { ok: false; reason: string };
+
+async function probe(name: string, url: string): Promise<ProbeOutcome> {
+  const controller = new AbortController();
+  const timer = setTimeout(() => controller.abort(), TIMEOUT_MS);
+  try {
+    const resp = await fetch(url, { method: 'GET', redirect: 'manual', signal: controller.signal });
+    if (resp.status >= 500) {
+      return { ok: false, reason: `${name} responded ${resp.status} (server-side error)` };
+    }
+    return { ok: true, status: resp.status };
+  } catch (err: unknown) {
+    const msg = err instanceof Error ? err.message : String(err);
+    return { ok: false, reason: `${name} unreachable (${msg})` };
+  } finally {
+    clearTimeout(timer);
+  }
+}
+
+export async function assertServicesHealthy(): Promise<void> {
+  const [web, api] = await Promise.all([
+    probe('Web', WEB_URL),
+    probe('API', API_URL),
+  ]);
+
+  const failures: string[] = [];
+  if (!web.ok) failures.push(`  - Web   ${WEB_URL} → ${web.reason}`);
+  if (!api.ok) failures.push(`  - API   ${API_URL} → ${api.reason}`);
+
+  if (failures.length > 0) {
+    const msg = [
+      '[e2e health-check] dev services are not healthy:',
+      ...failures,
+      '',
+      `Fix: ${RESTART_HINT}`,
+      '(or override URLs via AIDOP_E2E_WEB_HEALTH_URL / AIDOP_E2E_API_HEALTH_URL)',
+    ].join('\n');
+    throw new Error(msg);
+  }
+
+  // Concise success line so reviewers can confirm the gate ran.
+  console.log(`[e2e health-check] OK  Web=${web.status}  API=${api.status}`);
+}