Web 端 (Playwright): - fixtures: test-data 工厂 + API Client (乐观锁 version) + 增强 auth fixture - pages: LoginPage, PatientListPage, PatientDetailPage, HealthDataPage, AppointmentPage - flows: 患者全流程, 体征数据链路, 预约排班链路, 随访管理链路, 告警处理链路 - smoke tests 迁移到 smoke/ 目录,import 路径更新 - playwright.config.ts 更新: globalSetup 环境检查, 60s timeout, video retain 小程序端 (Vitest + miniprogram-automator): - helpers: AutomatorClient, MpApiClient, MpAuthHelper, MpNavigator - flows: 患者健康数据查看, 体征数据录入, 积分签到兑换, 积分商城浏览 - vitest.config.ts + check-readiness.ts - vitest 4.1.5 依赖安装 Playwright 发现 15 个测试 (5 flow + 10 smoke),全部就绪
71 lines
2.3 KiB
TypeScript
71 lines
2.3 KiB
TypeScript
// apps/miniprogram/e2e/helpers/api-client.ts
|
||
// 简化版 API Client,用于小程序 E2E 数据准备/清理
|
||
|
||
const API_BASE = process.env.E2E_API_URL || 'http://localhost:3000/api/v1';
|
||
|
||
export class MpApiClient {
|
||
private token = '';
|
||
|
||
async login(username?: string, password?: string) {
|
||
const res = await fetch(`${API_BASE}/auth/login`, {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({
|
||
username: username || process.env.E2E_ADMIN_USER || 'admin',
|
||
password: password || process.env.E2E_ADMIN_PASS || 'Admin@2026',
|
||
}),
|
||
});
|
||
const json = await res.json();
|
||
if (!json.success) throw new Error('Login failed');
|
||
this.token = json.data.access_token;
|
||
return json.data;
|
||
}
|
||
|
||
getToken() { return this.token; }
|
||
|
||
async createPatient(overrides?: Record<string, unknown>) {
|
||
return this.post('/health/patients', overrides ?? {});
|
||
}
|
||
|
||
async deletePatient(id: string, version: number) {
|
||
await this.del(`/health/patients/${id}`, { version });
|
||
}
|
||
|
||
async createVitalSigns(patientId: string, overrides?: Record<string, unknown>) {
|
||
return this.post(`/health/patients/${patientId}/vital-signs`, overrides ?? {});
|
||
}
|
||
|
||
async deleteVitalSigns(patientId: string, id: string, version: number) {
|
||
await this.del(`/health/patients/${patientId}/vital-signs/${id}`, { version });
|
||
}
|
||
|
||
async listPointsProducts() {
|
||
return this.get('/health/points/products');
|
||
}
|
||
|
||
private async headers() {
|
||
return { 'Content-Type': 'application/json', Authorization: `Bearer ${this.token}` };
|
||
}
|
||
|
||
private async get(path: string) {
|
||
const res = await fetch(`${API_BASE}${path}`, { headers: await this.headers() });
|
||
const json = await res.json();
|
||
return json.data;
|
||
}
|
||
|
||
private async post(path: string, body: unknown) {
|
||
const res = await fetch(`${API_BASE}${path}`, {
|
||
method: 'POST', headers: await this.headers(), body: JSON.stringify(body),
|
||
});
|
||
const json = await res.json();
|
||
if (!json.success) throw new Error(`POST ${path} failed`);
|
||
return json.data;
|
||
}
|
||
|
||
private async del(path: string, body?: unknown) {
|
||
await fetch(`${API_BASE}${path}`, {
|
||
method: 'DELETE', headers: await this.headers(), body: body ? JSON.stringify(body) : undefined,
|
||
});
|
||
}
|
||
}
|