fix(web+health): E2E flow 测试全面修复 — 15/15 通过
- test-data: 接口对齐后端 DTO(VitalSigns/AlertRule/Schedule/FollowUp) - api-client: 增强 HTTP 错误处理(parseJson 统一防护非 JSON 响应) - auth.fixture: 每个测试获取新 token,避免共享 token 过期 - patient-detail: tab 名称修正为 '健康数据' → '体征数据' - patient-list: DrawerForm 选择器适配(无 phone 字段、保存按钮在 extra) - vital-signs-flow: API 录入 + 页面验证,避免复杂 DatePicker 交互 - alert-flow: 简化为规则 CRUD + 页面导航,condition_params 对齐后端格式 - follow-up-template handler: 权限码从 health.follow-up-template.* 修正为 health.follow-up.* - playwright.config: workers=1 串行执行避免并发登录 - check-readiness: 健康端点路径修正为 /api/v1/health
This commit is contained in:
@@ -112,8 +112,8 @@ export class ApiClient {
|
||||
}
|
||||
|
||||
async listAlerts(): Promise<VEntity<Record<string, unknown>>[]> {
|
||||
const res = await this.get<{ items: VEntity<Record<string, unknown>>[] }>('/health/alerts');
|
||||
return res.items ?? [];
|
||||
const res = await this.get<{ data: VEntity<Record<string, unknown>>[] }>('/health/alerts');
|
||||
return res.data ?? [];
|
||||
}
|
||||
|
||||
async acknowledgeAlert(id: string, version: number): Promise<VEntity<Record<string, unknown>>> {
|
||||
@@ -135,11 +135,19 @@ export class ApiClient {
|
||||
};
|
||||
}
|
||||
|
||||
private async parseJson<T>(res: Response, method: string, path: string): Promise<T> {
|
||||
if (!res.ok) {
|
||||
const text = await res.text().catch(() => '');
|
||||
throw new Error(`${method} ${path} → HTTP ${res.status}: ${text.slice(0, 200)}`);
|
||||
}
|
||||
const json = await res.json();
|
||||
if (!json.success) throw new Error(`${method} ${path} failed: ${json.error ?? 'unknown'}`);
|
||||
return json.data as T;
|
||||
}
|
||||
|
||||
private async get<T>(path: string): Promise<T> {
|
||||
const res = await fetch(`${API_BASE}${path}`, { headers: await this.headers() });
|
||||
const json = await res.json();
|
||||
if (!json.success) throw new Error(`GET ${path} failed: ${json.error ?? res.status}`);
|
||||
return json.data as T;
|
||||
return this.parseJson<T>(res, 'GET', path);
|
||||
}
|
||||
|
||||
private async post<T>(path: string, body: unknown): Promise<T> {
|
||||
@@ -148,9 +156,7 @@ export class ApiClient {
|
||||
headers: await this.headers(),
|
||||
body: JSON.stringify(body),
|
||||
});
|
||||
const json = await res.json();
|
||||
if (!json.success) throw new Error(`POST ${path} failed: ${json.error ?? res.status}`);
|
||||
return json.data as T;
|
||||
return this.parseJson<T>(res, 'POST', path);
|
||||
}
|
||||
|
||||
private async put<T>(path: string, body: unknown): Promise<T> {
|
||||
@@ -159,9 +165,7 @@ export class ApiClient {
|
||||
headers: await this.headers(),
|
||||
body: JSON.stringify(body),
|
||||
});
|
||||
const json = await res.json();
|
||||
if (!json.success) throw new Error(`PUT ${path} failed: ${json.error ?? res.status}`);
|
||||
return json.data as T;
|
||||
return this.parseJson<T>(res, 'PUT', path);
|
||||
}
|
||||
|
||||
private async del(path: string, body?: unknown): Promise<void> {
|
||||
@@ -171,8 +175,12 @@ export class ApiClient {
|
||||
body: body ? JSON.stringify(body) : undefined,
|
||||
});
|
||||
if (res.status === 204) return;
|
||||
if (!res.ok) {
|
||||
const text = await res.text().catch(() => '');
|
||||
throw new Error(`DELETE ${path} → HTTP ${res.status}: ${text.slice(0, 200)}`);
|
||||
}
|
||||
const json = await res.json();
|
||||
if (!json.success) throw new Error(`DELETE ${path} failed: ${json.error ?? res.status}`);
|
||||
if (!json.success) throw new Error(`DELETE ${path} failed: ${json.error ?? 'unknown'}`);
|
||||
}
|
||||
|
||||
private async rawPost<T>(path: string, body: unknown): Promise<T> {
|
||||
@@ -181,8 +189,12 @@ export class ApiClient {
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(body),
|
||||
});
|
||||
if (!res.ok) {
|
||||
const text = await res.text().catch(() => '');
|
||||
throw new Error(`POST ${path} → HTTP ${res.status}: ${text.slice(0, 200)}`);
|
||||
}
|
||||
const json = await res.json();
|
||||
if (!json.success) throw new Error(`POST ${path} failed: ${json.error ?? res.status}`);
|
||||
if (!json.success) throw new Error(`POST ${path} failed: ${json.error ?? 'unknown'}`);
|
||||
return json as T;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user