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),全部就绪
191 lines
4.4 KiB
TypeScript
191 lines
4.4 KiB
TypeScript
// apps/web/e2e/fixtures/test-data.ts
|
||
|
||
export interface PatientData {
|
||
name: string;
|
||
gender?: string;
|
||
birth_date?: string;
|
||
blood_type?: string;
|
||
id_number?: string;
|
||
allergy_history?: string;
|
||
medical_history_summary?: string;
|
||
emergency_contact_name?: string;
|
||
emergency_contact_phone?: string;
|
||
source?: string;
|
||
notes?: string;
|
||
phone?: string;
|
||
}
|
||
|
||
export interface DoctorData {
|
||
name: string;
|
||
department?: string;
|
||
title?: string;
|
||
specialty?: string;
|
||
phone?: string;
|
||
license_number?: string;
|
||
status?: string;
|
||
}
|
||
|
||
export interface VitalSignsData {
|
||
systolic_bp?: number;
|
||
diastolic_bp?: number;
|
||
heart_rate?: number;
|
||
temperature?: number;
|
||
spo2?: number;
|
||
blood_glucose_fasting?: number;
|
||
blood_glucose_postprandial?: number;
|
||
weight?: number;
|
||
height?: number;
|
||
recorded_at?: string;
|
||
source?: string;
|
||
notes?: string;
|
||
}
|
||
|
||
export interface ScheduleData {
|
||
doctor_id: string;
|
||
date: string;
|
||
start_time: string;
|
||
end_time: string;
|
||
max_appointments?: number;
|
||
}
|
||
|
||
export interface AppointmentData {
|
||
patient_id: string;
|
||
doctor_id: string;
|
||
schedule_id: string;
|
||
appointment_date: string;
|
||
start_time: string;
|
||
end_time: string;
|
||
reason?: string;
|
||
}
|
||
|
||
export interface FollowUpTemplateData {
|
||
name: string;
|
||
description?: string;
|
||
frequency_days: number;
|
||
total_rounds: number;
|
||
questions?: string;
|
||
}
|
||
|
||
export interface FollowUpTaskData {
|
||
patient_id: string;
|
||
template_id: string;
|
||
assigned_to?: string;
|
||
due_date: string;
|
||
}
|
||
|
||
export interface AlertRuleData {
|
||
name: string;
|
||
indicator: string;
|
||
condition: string;
|
||
threshold: number;
|
||
severity: string;
|
||
description?: string;
|
||
}
|
||
|
||
let counter = 0;
|
||
|
||
function uid(): string {
|
||
counter += 1;
|
||
return `${Date.now()}_${counter}_${Math.random().toString(36).slice(2, 6)}`;
|
||
}
|
||
|
||
export function makePatient(overrides?: Partial<PatientData>): PatientData {
|
||
const id = uid();
|
||
return {
|
||
name: `E2E患者_${id}`,
|
||
gender: 'male',
|
||
birth_date: '1990-01-15',
|
||
phone: `138${String(Math.random()).slice(2, 11)}`,
|
||
id_number: `110101199001${String(Math.random()).slice(2, 8)}`,
|
||
...overrides,
|
||
};
|
||
}
|
||
|
||
export function makeDoctor(overrides?: Partial<DoctorData>): DoctorData {
|
||
const id = uid();
|
||
return {
|
||
name: `E2E医生_${id}`,
|
||
department: '内科',
|
||
title: '主治医师',
|
||
specialty: '全科',
|
||
license_number: `DOC${id}`,
|
||
...overrides,
|
||
};
|
||
}
|
||
|
||
export function makeVitalSigns(overrides?: Partial<VitalSignsData>): VitalSignsData {
|
||
return {
|
||
systolic_bp: 120,
|
||
diastolic_bp: 80,
|
||
heart_rate: 72,
|
||
temperature: 36.5,
|
||
spo2: 98,
|
||
source: 'web_e2e',
|
||
...overrides,
|
||
};
|
||
}
|
||
|
||
export function makeSchedule(doctorId: string, overrides?: Partial<ScheduleData>): ScheduleData {
|
||
const tomorrow = new Date();
|
||
tomorrow.setDate(tomorrow.getDate() + 1);
|
||
const date = tomorrow.toISOString().slice(0, 10);
|
||
return {
|
||
doctor_id: doctorId,
|
||
date,
|
||
start_time: '09:00',
|
||
end_time: '12:00',
|
||
max_appointments: 10,
|
||
...overrides,
|
||
};
|
||
}
|
||
|
||
export function makeAppointment(patientId: string, doctorId: string, scheduleId: string, overrides?: Partial<AppointmentData>): AppointmentData {
|
||
const tomorrow = new Date();
|
||
tomorrow.setDate(tomorrow.getDate() + 1);
|
||
const date = tomorrow.toISOString().slice(0, 10);
|
||
return {
|
||
patient_id: patientId,
|
||
doctor_id: doctorId,
|
||
schedule_id: scheduleId,
|
||
appointment_date: date,
|
||
start_time: '09:00',
|
||
end_time: '10:00',
|
||
reason: 'E2E测试预约',
|
||
...overrides,
|
||
};
|
||
}
|
||
|
||
export function makeFollowUpTemplate(overrides?: Partial<FollowUpTemplateData>): FollowUpTemplateData {
|
||
return {
|
||
name: `E2E随访模板_${uid()}`,
|
||
description: 'E2E自动创建的随访模板',
|
||
frequency_days: 7,
|
||
total_rounds: 3,
|
||
questions: JSON.stringify([{ question: '血压是否正常?', type: 'yes_no' }]),
|
||
...overrides,
|
||
};
|
||
}
|
||
|
||
export function makeFollowUpTask(patientId: string, templateId: string, overrides?: Partial<FollowUpTaskData>): FollowUpTaskData {
|
||
const dueDate = new Date();
|
||
dueDate.setDate(dueDate.getDate() + 7);
|
||
return {
|
||
patient_id: patientId,
|
||
template_id: templateId,
|
||
due_date: dueDate.toISOString().slice(0, 10),
|
||
...overrides,
|
||
};
|
||
}
|
||
|
||
export function makeAlertRule(overrides?: Partial<AlertRuleData>): AlertRuleData {
|
||
return {
|
||
name: `E2E告警规则_${uid()}`,
|
||
indicator: 'heart_rate',
|
||
condition: 'greater_than',
|
||
threshold: 50,
|
||
severity: 'warning',
|
||
description: 'E2E测试低阈值规则,用于触发告警',
|
||
...overrides,
|
||
};
|
||
}
|