Files
everything-is-suitable/everything-is-suitable-test/e2e/core/data-strategy-manager.ts
T
张翔 08ea5fbe98 feat(admin): 添加用户管理相关文件
添加用户管理视图、API和状态管理文件
2026-03-28 14:37:29 +08:00

255 lines
6.9 KiB
TypeScript

import { test } from '@playwright/test';
import { testLogger } from '../shared/utils/test-logger';
import { testDataGenerator, UserData, RoleData, MenuData } from './test-data';
export type DataStrategy = 'real' | 'mock' | 'hybrid';
export interface DataStrategyConfig {
strategy: DataStrategy;
mockEnabled: boolean;
realDataEnabled: boolean;
autoCleanup: boolean;
}
export interface DataSnapshot {
name: string;
timestamp: number;
data: Map<string, any[]>;
}
export class DataStrategyManager {
private strategy: DataStrategy;
private config: DataStrategyConfig;
private snapshots: Map<string, DataSnapshot> = new Map();
private testData: Map<string, any[]> = new Map();
constructor(config?: Partial<DataStrategyConfig>) {
this.config = {
strategy: 'hybrid',
mockEnabled: true,
realDataEnabled: true,
autoCleanup: true,
...config
};
this.strategy = this.config.strategy;
testLogger.info(`DataStrategyManager initialized with strategy: ${this.strategy}`);
}
setStrategy(strategy: DataStrategy): void {
this.strategy = strategy;
this.config.strategy = strategy;
testLogger.info(`Data strategy changed to: ${strategy}`);
}
getStrategy(): DataStrategy {
return this.strategy;
}
getConfig(): DataStrategyConfig {
return { ...this.config };
}
selectDataSource(testTags: string[]): DataStrategy {
testLogger.debug(`Selecting data source for tags: ${testTags.join(', ')}`);
if (this.config.strategy === 'real') {
testLogger.debug('Using real data strategy (forced)');
return 'real';
}
if (this.config.strategy === 'mock') {
testLogger.debug('Using mock data strategy (forced)');
return 'mock';
}
if (this.config.strategy === 'hybrid') {
return this.selectHybridDataSource(testTags);
}
return 'mock';
}
private selectHybridDataSource(testTags: string[]): DataStrategy {
const hasSmokeTag = testTags.includes('@smoke');
const hasRegressionTag = testTags.includes('@regression');
const hasFullTag = testTags.includes('@full');
const hasCriticalTag = testTags.includes('@critical');
if (hasCriticalTag) {
testLogger.debug('Hybrid strategy: Using real data for @critical tests');
return 'real';
}
if (hasFullTag) {
testLogger.debug('Hybrid strategy: Using real data for @full tests');
return 'real';
}
if (hasRegressionTag) {
testLogger.debug('Hybrid strategy: Using hybrid data for @regression tests');
return 'hybrid';
}
if (hasSmokeTag) {
testLogger.debug('Hybrid strategy: Using mock data for @smoke tests');
return 'mock';
}
testLogger.debug('Hybrid strategy: Defaulting to mock data');
return 'mock';
}
async createData(dataType: string, data: any, testTags: string[] = []): Promise<any> {
const dataSource = this.selectDataSource(testTags);
testLogger.info(`Creating ${dataType} using ${dataSource} data source`);
if (dataSource === 'mock') {
return this.createMockData(dataType, data);
}
if (dataSource === 'real') {
return this.createRealData(dataType, data);
}
return this.createHybridData(dataType, data);
}
private createMockData(dataType: string, data: any): any {
testLogger.debug(`Creating mock data for ${dataType}`);
switch (dataType) {
case 'user':
return testDataGenerator.generateUserData(data);
case 'role':
return testDataGenerator.generateRoleData(data);
case 'menu':
return testDataGenerator.generateMenuData(data);
case 'permission':
return testDataGenerator.generatePermissionData(data);
default:
return data;
}
}
private createRealData(dataType: string, data: any): any {
testLogger.debug(`Creating real data for ${dataType} (requires API connection)`);
return data;
}
private createHybridData(dataType: string, data: any): any {
testLogger.debug(`Creating hybrid data for ${dataType}`);
const mockData = this.createMockData(dataType, data);
const realData = this.createRealData(dataType, data);
return {
...mockData,
_dataSource: 'hybrid',
_mockData: mockData,
_realData: realData
};
}
async cleanupData(dataType: string, dataId: string | number): Promise<void> {
testLogger.info(`Cleaning up ${dataType} with id: ${dataId}`);
if (this.config.autoCleanup) {
this.removeTestData(dataType, dataId);
}
}
async cleanupAll(): Promise<void> {
testLogger.info('Cleaning up all test data');
this.testData.clear();
this.snapshots.clear();
testLogger.info('All test data cleaned up');
}
async createSnapshot(snapshotName: string): Promise<DataSnapshot> {
testLogger.info(`Creating snapshot: ${snapshotName}`);
const snapshot: DataSnapshot = {
name: snapshotName,
timestamp: Date.now(),
data: new Map(this.testData)
};
this.snapshots.set(snapshotName, snapshot);
testLogger.info(`Snapshot created: ${snapshotName} at ${new Date(snapshot.timestamp).toISOString()}`);
return snapshot;
}
async rollbackToSnapshot(snapshotName: string): Promise<void> {
testLogger.info(`Rolling back to snapshot: ${snapshotName}`);
const snapshot = this.snapshots.get(snapshotName);
if (!snapshot) {
throw new Error(`Snapshot not found: ${snapshotName}`);
}
this.testData = new Map(snapshot.data);
testLogger.info(`Rolled back to snapshot: ${snapshotName}`);
}
private addTestData(dataType: string, data: any): void {
if (!this.testData.has(dataType)) {
this.testData.set(dataType, []);
}
this.testData.get(dataType)!.push(data);
}
private removeTestData(dataType: string, dataId: string | number): void {
const items = this.testData.get(dataType);
if (items) {
const index = items.findIndex(item => item.id === dataId);
if (index !== -1) {
items.splice(index, 1);
}
}
}
getTestData(dataType: string): any[] {
return this.testData.get(dataType) || [];
}
getSnapshot(snapshotName: string): DataSnapshot | undefined {
return this.snapshots.get(snapshotName);
}
getAllSnapshots(): DataSnapshot[] {
return Array.from(this.snapshots.values());
}
deleteSnapshot(snapshotName: string): void {
this.snapshots.delete(snapshotName);
testLogger.info(`Snapshot deleted: ${snapshotName}`);
}
getStatistics(): {
totalTestData: number;
totalSnapshots: number;
strategy: DataStrategy;
config: DataStrategyConfig;
} {
let totalTestData = 0;
const testDataValues = Array.from(this.testData.values());
for (const items of testDataValues) {
totalTestData += items.length;
}
return {
totalTestData,
totalSnapshots: this.snapshots.size,
strategy: this.strategy,
config: this.getConfig()
};
}
}
export const dataStrategyManager = new DataStrategyManager();