feat(admin): 添加用户管理相关文件
添加用户管理视图、API和状态管理文件
This commit is contained in:
@@ -0,0 +1,196 @@
|
||||
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<string, number[]> = 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<number> {
|
||||
const startTime = Date.now();
|
||||
await page.goto(url, { waitUntil: 'networkidle' });
|
||||
const endTime = Date.now();
|
||||
return endTime - startTime;
|
||||
}
|
||||
|
||||
static async measureApiCall(page: Page, apiCall: () => Promise<void>): Promise<number> {
|
||||
const startTime = Date.now();
|
||||
await apiCall();
|
||||
const endTime = Date.now();
|
||||
return endTime - startTime;
|
||||
}
|
||||
|
||||
static async measureElementInteraction(
|
||||
page: Page,
|
||||
selector: string,
|
||||
action: () => Promise<void>
|
||||
): Promise<number> {
|
||||
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<number> {
|
||||
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<number> {
|
||||
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);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user