Files
gym-manage/gym-manage-web/e2e/journeys/performance.spec.ts
T

105 lines
3.8 KiB
TypeScript

import { test, expect } from '@playwright/test';
test.describe('页面性能测试', () => {
test('Dashboard 页面性能', async ({ page }) => {
const metrics: { name: string; duration: number }[] = [];
await test.step('测量Dashboard完整加载时间', async () => {
const startTime = Date.now();
await page.goto('/dashboard');
await page.waitForLoadState('networkidle');
const loadTime = Date.now() - startTime;
metrics.push({ name: 'Dashboard-TotalLoad', duration: loadTime });
console.log(`Dashboard 完整加载耗时: ${loadTime}ms`);
expect(loadTime).toBeLessThan(15000);
});
await test.step('测量Dashboard首屏渲染时间', async () => {
const startTime = Date.now();
await page.goto('/dashboard');
await page.waitForSelector('.el-table, .dashboard, [class*="dashboard"]', { timeout: 10000 });
const renderTime = Date.now() - startTime;
metrics.push({ name: 'Dashboard-FirstRender', duration: renderTime });
console.log(`Dashboard 首屏渲染耗时: ${renderTime}ms`);
expect(renderTime).toBeLessThan(10000);
});
await test.step('测量API响应时间', async () => {
const responseTimings: number[] = [];
page.on('response', (response) => {
if (response.url().includes('/api/')) {
const timing = response.request().timing();
if (timing) {
responseTimings.push(timing.responseEnd - timing.startTime);
}
}
});
await page.goto('/dashboard');
await page.waitForLoadState('networkidle');
if (responseTimings.length > 0) {
const avgResponseTime = responseTimings.reduce((a, b) => a + b, 0) / responseTimings.length;
metrics.push({ name: 'Dashboard-API-AvgResponse', duration: Math.round(avgResponseTime) });
console.log(`Dashboard API 平均响应时间: ${Math.round(avgResponseTime)}ms`);
expect(avgResponseTime).toBeLessThan(5000);
}
});
console.log('\n=== Dashboard 性能报告 ===');
metrics.forEach(m => console.log(` ${m.name}: ${m.duration}ms`));
});
test('团课管理页面性能', async ({ page }) => {
await test.step('测量团课管理页面加载时间', async () => {
const startTime = Date.now();
await page.goto('/courses');
await page.waitForLoadState('networkidle');
const loadTime = Date.now() - startTime;
console.log(`团课管理页面加载耗时: ${loadTime}ms`);
expect(loadTime).toBeLessThan(15000);
});
await test.step('验证表格首屏渲染', async () => {
const startTime = Date.now();
await page.goto('/courses');
await page.waitForSelector('.el-table', { timeout: 10000 });
const tableTime = Date.now() - startTime;
console.log(`团课管理表格渲染耗时: ${tableTime}ms`);
expect(tableTime).toBeLessThan(10000);
});
});
test('导航切换性能', async ({ page }) => {
await test.step('登录并测量页面间导航性能', async () => {
const navTimings: number[] = [];
const pages = ['/users', '/roles', '/menus', '/courses', '/members'];
for (const path of pages) {
const startTime = Date.now();
await page.goto(path);
await page.waitForLoadState('networkidle');
const navTime = Date.now() - startTime;
navTimings.push(navTime);
console.log(`导航到 ${path}: ${navTime}ms`);
}
const avgNavTime = navTimings.reduce((a, b) => a + b, 0) / navTimings.length;
console.log(`平均导航时间: ${Math.round(avgNavTime)}ms`);
// 每个页面切换应在 5 秒内
for (const time of navTimings) {
expect(time).toBeLessThan(5000);
}
});
});
});