import { test, expect, Page } from '@playwright/test'; import { LoginPage } from '../pages/login-page'; import { testConfig } from '../core/test-config'; export class PerformanceMetrics { private metrics: Map = new Map(); recordMetric(name: string, value: number) { if (!this.metrics.has(name)) { this.metrics.set(name, []); } this.metrics.get(name)!.push(value); } getAverage(name: string): number { const values = this.metrics.get(name) || []; if (values.length === 0) return 0; const sum = values.reduce((a, b) => a + b, 0); return sum / values.length; } getP95(name: string): number { const values = this.metrics.get(name) || []; if (values.length === 0) return 0; const sorted = [...values].sort((a, b) => a - b); const index = Math.floor(sorted.length * 0.95); return sorted[index]; } getP99(name: string): number { const values = this.metrics.get(name) || []; if (values.length === 0) return 0; const sorted = [...values].sort((a, b) => a - b); const index = Math.floor(sorted.length * 0.99); return sorted[index]; } getMax(name: string): number { const values = this.metrics.get(name) || []; if (values.length === 0) return 0; return Math.max(...values); } getMin(name: string): number { const values = this.metrics.get(name) || []; if (values.length === 0) return 0; return Math.min(...values); } printReport() { console.log('\n=== 性能测试报告 ==='); for (const [name, values] of this.metrics.entries()) { console.log(`\n${name}:`); console.log(` 平均值: ${this.getAverage(name).toFixed(2)}ms`); console.log(` P95: ${this.getP95(name).toFixed(2)}ms`); console.log(` P99: ${this.getP99(name).toFixed(2)}ms`); console.log(` 最大值: ${this.getMax(name).toFixed(2)}ms`); console.log(` 最小值: ${this.getMin(name).toFixed(2)}ms`); console.log(` 样本数: ${values.length}`); } console.log('\n====================\n'); } } export class PerformanceTestHelper { static async measurePageLoad(page: Page, url: string): Promise { const startTime = Date.now(); await page.goto(url, { waitUntil: 'networkidle' }); const endTime = Date.now(); return endTime - startTime; } static async measureApiCall(page: Page, apiCall: () => Promise): Promise { const startTime = Date.now(); await apiCall(); const endTime = Date.now(); return endTime - startTime; } static async measureElementInteraction( page: Page, selector: string, action: () => Promise ): Promise { await page.waitForSelector(selector, { state: 'visible' }); const startTime = Date.now(); await action(); const endTime = Date.now(); return endTime - startTime; } static async measurePageNavigation( page: Page, fromUrl: string, toUrl: string ): Promise { await page.goto(fromUrl, { waitUntil: 'networkidle' }); const startTime = Date.now(); await page.goto(toUrl, { waitUntil: 'networkidle' }); const endTime = Date.now(); return endTime - startTime; } static async measureMemoryUsage(page: Page): Promise<{ used: number; total: number }> { const metrics = await page.evaluate(() => { if (performance && (performance as any).memory) { return { used: (performance as any).memory.usedJSHeapSize, total: (performance as any).memory.totalJSHeapSize }; } return { used: 0, total: 0 }; }); return metrics; } static async measureNetworkRequests(page: Page): Promise { let requestCount = 0; page.on('request', () => { requestCount++; }); return requestCount; } static async clearCacheAndCookies(page: Page) { await page.context().clearCookies(); await page.context().clearPermissions(); } } test.describe.configure({ mode: 'serial', timeout: 120000 }); test.describe('性能测试 - 页面加载性能', () => { const metrics = new PerformanceMetrics(); const helper = new PerformanceTestHelper(); test.afterAll(() => { metrics.printReport(); }); test('PT-001: 登录页面加载性能', async ({ page }) => { const loadTime = await helper.measurePageLoad(page, testConfig.getBaseURL()); metrics.recordMetric('登录页面加载时间', loadTime); expect(loadTime).toBeLessThan(3000); }); test('PT-002: 仪表盘页面加载性能', async ({ page }) => { const loginPage = new LoginPage(page); await page.goto(testConfig.getBaseURL()); await loginPage.login('admin', 'admin123'); const loadTime = await helper.measurePageLoad(page, `${testConfig.getBaseURL()}/dashboard`); metrics.recordMetric('仪表盘页面加载时间', loadTime); expect(loadTime).toBeLessThan(2000); }); test('PT-003: 用户管理页面加载性能', async ({ page }) => { const loginPage = new LoginPage(page); await page.goto(testConfig.getBaseURL()); await loginPage.login('admin', 'admin123'); const loadTime = await helper.measurePageLoad(page, `${testConfig.getBaseURL()}/users`); metrics.recordMetric('用户管理页面加载时间', loadTime); expect(loadTime).toBeLessThan(2000); }); test('PT-004: 黄历页面加载性能', async ({ page }) => { const loginPage = new LoginPage(page); await page.goto(testConfig.getBaseURL()); await loginPage.login('admin', 'admin123'); const loadTime = await helper.measurePageLoad(page, `${testConfig.getBaseURL()}/almanac`); metrics.recordMetric('黄历页面加载时间', loadTime); expect(loadTime).toBeLessThan(2000); }); test('PT-005: 运势页面加载性能', async ({ page }) => { const loginPage = new LoginPage(page); await page.goto(testConfig.getBaseURL()); await loginPage.login('admin', 'admin123'); const loadTime = await helper.measurePageLoad(page, `${testConfig.getBaseURL()}/fortune`); metrics.recordMetric('运势页面加载时间', loadTime); expect(loadTime).toBeLessThan(2000); }); });