diff --git a/e2e/src/tests/mobile/performance/mobile-performance.spec.ts b/e2e/src/tests/mobile/performance/mobile-performance.spec.ts new file mode 100644 index 0000000..f34f3b5 --- /dev/null +++ b/e2e/src/tests/mobile/performance/mobile-performance.spec.ts @@ -0,0 +1,72 @@ +import { test, expect } from '@playwright/test'; +import { getMobileDevices } from '../../../utils/devices'; +import { networkConfigs } from '../../../config/network-configs'; +import { MobilePerformanceMonitor } from '../../../utils/MobilePerformanceMonitor'; +import { MobileTestDataGenerator } from '../../../utils/MobileTestDataGenerator'; + +test.describe('移动端性能测试 @mobile @performance', () => { + const devices = getMobileDevices().slice(0, 3); + const networkTypes = ['wifi-fast', '4g-lte', '3g-fast', '2g-slow'] as const; + + for (const device of devices) { + for (const network of networkTypes) { + test(`${device.name} - ${networkConfigs[network].name} - 首屏加载性能`, async ({ page }) => { + await page.setViewportSize(device.viewport); + + await page.goto('/'); + await page.waitForLoadState('networkidle'); + + const monitor = new MobilePerformanceMonitor(page); + const vitals = await monitor.getCoreWebVitals(); + + const baseline = MobileTestDataGenerator.generatePerformanceBaseline(device.name, network); + + expect(vitals.LCP).toBeLessThan(baseline.LCP); + expect(vitals.FCP).toBeLessThan(baseline.FCP); + expect(vitals.CLS).toBeLessThan(baseline.CLS); + }); + } + } + + test('移动端 - 交互响应性能', async ({ page }) => { + await page.setViewportSize({ width: 375, height: 667 }); + await page.goto('/'); + + const monitor = new MobilePerformanceMonitor(page); + const vitals = await monitor.getCoreWebVitals(); + + expect(vitals.FCP).toBeLessThan(2000); + expect(vitals.LCP).toBeLessThan(3000); + expect(vitals.CLS).toBeLessThan(0.25); + }); + + test('移动端 - 页面资源加载性能', async ({ page }) => { + await page.setViewportSize({ width: 390, height: 844 }); + await page.goto('/'); + + const resources = await page.evaluate(() => { + return performance.getEntriesByType('resource').map(r => ({ + name: r.name, + duration: r.duration, + size: r.transferSize, + })); + }); + + const largeResources = resources.filter(r => r.size > 100000); + expect(largeResources.length).toBeLessThan(5); + }); + + test('移动端 - JavaScript 执行性能', async ({ page }) => { + await page.setViewportSize({ width: 414, height: 896 }); + await page.goto('/'); + + const jsMetrics = await page.evaluate(() => { + return { + totalTasks: performance.getEntriesByType('measure').length, + longTasks: performance.getEntriesByType('measure').filter((m: any) => m.duration > 50).length, + }; + }); + + expect(jsMetrics.longTasks).toBeLessThan(10); + }); +}); \ No newline at end of file