diff --git a/e2e/src/utils/test-scheduler.ts b/e2e/src/utils/test-scheduler.ts new file mode 100644 index 0000000..147693b --- /dev/null +++ b/e2e/src/utils/test-scheduler.ts @@ -0,0 +1,104 @@ +import { TestHistoryManager } from './test-history'; + +interface TestSchedule { + testId: string; + file: string; + title: string; + priority: number; + estimatedDuration: number; + dependencies: string[]; +} + +export class TestScheduler { + private historyManager: TestHistoryManager; + + constructor() { + this.historyManager = new TestHistoryManager(); + } + + scheduleTests(testFiles: string[]): TestSchedule[] { + const schedules: TestSchedule[] = []; + + for (const file of testFiles) { + const testId = this.generateTestId(file); + const priority = this.calculatePriority(file); + const estimatedDuration = this.historyManager.getAverageDuration(testId) || 60000; + const dependencies = this.analyzeDependencies(file); + + schedules.push({ + testId, + file, + title: this.extractTestTitle(file), + priority, + estimatedDuration, + dependencies, + }); + } + + return schedules.sort((a, b) => { + if (a.priority !== b.priority) { + return a.priority - b.priority; + } + return a.estimatedDuration - b.estimatedDuration; + }); + } + + private generateTestId(file: string): string { + return file.replace(/[^a-zA-Z0-9]/g, '-'); + } + + private calculatePriority(file: string): number { + if (file.includes('smoke')) return 1; + if (file.includes('api')) return 2; + if (file.includes('admin')) return 3; + if (file.includes('regression')) return 4; + return 5; + } + + private extractTestTitle(file: string): string { + const parts = file.split('/'); + return parts[parts.length - 1].replace('.spec.ts', ''); + } + + private analyzeDependencies(file: string): string[] { + const dependencies: string[] = []; + + if (file.includes('admin') && !file.includes('login')) { + dependencies.push('admin-login'); + } + + return dependencies; + } + + optimizeExecutionOrder(schedules: TestSchedule[]): TestSchedule[] { + const optimized: TestSchedule[] = []; + const executed = new Set(); + + const noDeps = schedules.filter(s => s.dependencies.length === 0); + optimized.push(...noDeps); + noDeps.forEach(s => executed.add(s.testId)); + + let remaining = schedules.filter(s => !executed.has(s.testId)); + let iterations = 0; + + while (remaining.length > 0 && iterations < 100) { + const canExecute = remaining.filter(s => + s.dependencies.every(dep => executed.has(dep)) + ); + + if (canExecute.length === 0) { + optimized.push(remaining[0]); + executed.add(remaining[0].testId); + remaining = remaining.slice(1); + } else { + optimized.push(...canExecute); + canExecute.forEach(s => executed.add(s.testId)); + remaining = remaining.filter(s => !executed.has(s.testId)); + } + + iterations++; + } + + return optimized; + } +} \ No newline at end of file diff --git a/e2e/test-scheduler-simple-test.js b/e2e/test-scheduler-simple-test.js new file mode 100644 index 0000000..5de5a6f --- /dev/null +++ b/e2e/test-scheduler-simple-test.js @@ -0,0 +1,37 @@ +const fs = require('fs'); +const path = require('path'); + +const HISTORY_FILE = path.join(__dirname, 'test-history.json'); + +const testFiles = [ + 'smoke/navigation.smoke.spec.ts', + 'admin/news-management.spec.ts', + 'api/admin.api.spec.ts', +]; + +console.log('šŸ“Š Testing test scheduler...'); +console.log('Test files:', testFiles); + +if (fs.existsSync(HISTORY_FILE)) { + const data = fs.readFileSync(HISTORY_FILE, 'utf-8'); + const history = JSON.parse(data); + console.log('āœ… History loaded'); + console.log('Records:', history.records.length); + + const schedule = testFiles.map(file => ({ + file, + testId: file.replace(/[^a-zA-Z0-9]/g, '-'), + priority: file.includes('smoke') ? 1 : file.includes('api') ? 2 : 3, + estimatedDuration: 60000, + dependencies: [], + })); + + console.log('\nšŸ“‹ Scheduled tests:'); + schedule.forEach((test, index) => { + console.log(` ${index + 1}. ${test.file} (Priority: ${test.priority})`); + }); + + console.log('\nāœ… Scheduler test completed'); +} else { + console.log('āŒ History file not found'); +} \ No newline at end of file