Files
wenzi/frontend/e2e/fixtures/test-data.ts
Your Name 91a0b77f7a test(cache): 修复CacheConfigTest边界值测试
- 修改 shouldVerifyCacheManager_withMaximumIntegerTtl 为 shouldVerifyCacheManager_withMaximumAllowedTtl
- 使用正确的最大TTL值(10080分钟,7天)而不是 Integer.MAX_VALUE
- 新增 shouldThrowException_whenTtlExceedsMaximum 测试验证边界检查
- 所有1266个测试用例通过
- 覆盖率: 指令81.89%, 行88.48%, 分支51.55%

docs: 添加项目状态报告
- 生成 PROJECT_STATUS_REPORT.md 详细记录项目当前状态
- 包含质量指标、已完成功能、待办事项和技术债务
2026-03-02 13:31:54 +08:00

213 lines
5.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { test as baseTest, expect, Page, APIRequestContext } from '@playwright/test';
import * as fs from 'fs';
import * as path from 'path';
import { fileURLToPath } from 'url';
/**
* E2E测试夹具Fixtures
* 提供测试数据、API客户端、认证信息等
*/
// 测试数据接口
export interface TestData {
activityId: number;
apiKey: string;
userId: number;
shortCode: string;
baseUrl: string;
apiBaseUrl: string;
}
// API响应类型
export interface ApiResponse<T = any> {
code: number;
message: string;
data: T;
}
// API客户端类
export class ApiClient {
constructor(
private request: APIRequestContext,
private apiKey: string,
private userToken: string,
private baseURL: string
) {}
/**
* 发送认证请求
*/
async get<T>(endpoint: string, headers?: Record<string, string>): Promise<ApiResponse<T>> {
const response = await this.request.get(`${this.baseURL}${endpoint}`, {
headers: {
'X-API-Key': this.apiKey,
'Authorization': `Bearer ${this.userToken}`,
...headers,
},
});
return await response.json();
}
/**
* 发送POST请求
*/
async post<T>(endpoint: string, data: any, headers?: Record<string, string>): Promise<ApiResponse<T>> {
const response = await this.request.post(`${this.baseURL}${endpoint}`, {
data,
headers: {
'Content-Type': 'application/json',
'X-API-Key': this.apiKey,
'Authorization': `Bearer ${this.userToken}`,
...headers,
},
});
return await response.json();
}
/**
* 验证API Key
*/
async validateApiKey(apiKey: string): Promise<boolean> {
try {
const response = await this.request.post(`${this.baseURL}/api/v1/api-keys/validate`, {
data: { apiKey },
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${this.userToken}`,
},
});
return response.status() === 200;
} catch (error) {
return false;
}
}
/**
* 获取活动列表
*/
async getActivities(): Promise<ApiResponse<any[]>> {
return this.get('/api/v1/activities');
}
/**
* 获取活动详情
*/
async getActivity(activityId: number): Promise<ApiResponse<any>> {
return this.get(`/api/v1/activities/${activityId}`);
}
/**
* 获取活动统计
*/
async getActivityStats(activityId: number): Promise<ApiResponse<any>> {
return this.get(`/api/v1/activities/${activityId}/stats`);
}
/**
* 获取排行榜
*/
async getLeaderboard(activityId: number, page: number = 0, size: number = 10): Promise<ApiResponse<any>> {
return this.get(`/api/v1/activities/${activityId}/leaderboard?page=${page}&size=${size}`);
}
/**
* 创建短链
*/
async createShortLink(originalUrl: string, activityId: number): Promise<ApiResponse<any>> {
return this.post('/api/v1/internal/shorten', {
originalUrl,
activityId,
});
}
/**
* 获取分享指标
*/
async getShareMetrics(activityId: number): Promise<ApiResponse<any>> {
return this.get(`/api/v1/share/metrics?activityId=${activityId}`);
}
}
/**
* 加载测试数据
*/
function loadTestData(): TestData {
// ES模块中获取当前文件目录
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const testDataPath = path.join(__dirname, '..', '.e2e-test-data.json');
// 默认测试数据
const defaultData: TestData = {
activityId: 1,
apiKey: 'test-api-key',
userId: 10001,
shortCode: 'test123',
baseUrl: process.env.PLAYWRIGHT_BASE_URL || 'http://localhost:5173',
apiBaseUrl: process.env.API_BASE_URL || 'http://localhost:8080',
};
try {
if (fs.existsSync(testDataPath)) {
const data = JSON.parse(fs.readFileSync(testDataPath, 'utf-8'));
return {
...defaultData,
...data,
};
}
} catch (error) {
console.warn('无法加载测试数据,使用默认值');
}
return defaultData;
}
/**
* 扩展的测试夹具类型
*/
export interface TestFixtures {
testData: TestData;
apiClient: ApiClient;
authenticatedPage: Page;
}
/**
* 创建扩展的test对象
*/
export const test = baseTest.extend<TestFixtures>({
// 测试数据
testData: async ({}, use) => {
const data = loadTestData();
await use(data);
},
// API客户端
apiClient: async ({ request, testData }, use) => {
const client = new ApiClient(
request,
testData.apiKey,
'test-e2e-token',
testData.apiBaseUrl
);
await use(client);
},
// 已认证的页面
authenticatedPage: async ({ page, testData }, use) => {
// 设置localStorage模拟登录状态
await page.addInitScript((data) => {
localStorage.setItem('token', 'test-e2e-token');
localStorage.setItem('userId', data.userId.toString());
localStorage.setItem('apiKey', data.apiKey);
localStorage.setItem('activityId', data.activityId.toString());
}, testData);
await use(page);
},
});
export { expect };