upskill-event-manager/wordpress-dev/tests/e2e/utils/VerbosityController.ts
bengizmo d6211ee364 feat(testing): Implement HVAC_Test_User_Factory and update .gitignore
- Add HVAC_Test_User_Factory class with:
  * User creation with specific roles
  * Multiple role support
  * Persona management system
  * Account cleanup integration
- Create comprehensive test suite in HVAC_Test_User_Factory_Test.php
- Update testing improvement plan documentation
- Add implementation decisions to project memory bank
- Restructure .gitignore with:
  * Whitelist approach for better file management
  * Explicit backup exclusions
  * Specific bin directory inclusions

Part of the Account Management component from the testing framework improvement plan.
2025-04-14 17:41:36 -03:00

187 lines
No EOL
5.8 KiB
TypeScript

import { TestInfo } from '@playwright/test';
import fs from 'fs/promises';
import path from 'path';
export enum VerbosityLevel {
SILENT = 0,
MINIMAL = 1,
NORMAL = 2,
VERBOSE = 3,
DEBUG = 4,
ERROR = 5 // Added ERROR level for error logging
}
export interface VerbosityOptions {
consoleOutput: boolean;
screenshots: boolean;
htmlDumps: boolean;
fileLogs: boolean;
performanceMetrics: boolean;
}
export class VerbosityController {
private static instance: VerbosityController;
private currentLevel: VerbosityLevel;
private options: Map<VerbosityLevel, VerbosityOptions>;
private constructor() {
this.currentLevel = VerbosityLevel.NORMAL; // Default level
this.options = new Map([
[VerbosityLevel.SILENT, {
consoleOutput: false,
screenshots: false,
htmlDumps: false,
fileLogs: false,
performanceMetrics: false
}],
[VerbosityLevel.MINIMAL, {
consoleOutput: true,
screenshots: false,
htmlDumps: false,
fileLogs: true,
performanceMetrics: false
}],
[VerbosityLevel.NORMAL, {
consoleOutput: true,
screenshots: true,
htmlDumps: true,
fileLogs: true,
performanceMetrics: true
}],
[VerbosityLevel.VERBOSE, {
consoleOutput: true,
screenshots: true,
htmlDumps: true,
fileLogs: true,
performanceMetrics: true
}],
[VerbosityLevel.DEBUG, {
consoleOutput: true,
screenshots: true,
htmlDumps: true,
fileLogs: true,
performanceMetrics: true
}],
[VerbosityLevel.ERROR, {
consoleOutput: true,
screenshots: true,
htmlDumps: true,
fileLogs: true,
performanceMetrics: true
}]
]);
}
static getInstance(): VerbosityController {
if (!VerbosityController.instance) {
VerbosityController.instance = new VerbosityController();
}
return VerbosityController.instance;
}
setLevel(level: VerbosityLevel): void {
this.currentLevel = level;
}
getLevel(): VerbosityLevel {
return this.currentLevel;
}
shouldLog(messageLevel: VerbosityLevel): boolean {
return messageLevel <= this.currentLevel;
}
getOptions(): VerbosityOptions {
return this.options.get(this.currentLevel) || this.options.get(VerbosityLevel.NORMAL)!;
}
async log(
message: string,
level: VerbosityLevel,
testInfo?: TestInfo,
error?: Error
): Promise<void> {
if (!this.shouldLog(level)) return;
const options = this.getOptions();
if (!options.consoleOutput) return;
const timestamp = new Date().toISOString();
const prefix = `[${timestamp}] [${VerbosityLevel[level]}]`;
// Console output
if (level === VerbosityLevel.ERROR || error) {
console.error(`${prefix} ${message}`, error || '');
} else {
console.log(`${prefix} ${message}`);
}
// File logging
if (options.fileLogs && testInfo) {
await this.logToFile(testInfo, `${prefix} ${message}\n${error ? error.stack : ''}\n`);
}
}
async shouldTakeScreenshot(testInfo: TestInfo): Promise<boolean> {
const options = this.getOptions();
if (!options.screenshots) return false;
// Additional conditions based on verbosity level
switch (this.currentLevel) {
case VerbosityLevel.VERBOSE:
case VerbosityLevel.DEBUG:
return true; // Take screenshots for all actions
case VerbosityLevel.NORMAL:
return testInfo.status !== 'passed'; // Only for non-passing tests
case VerbosityLevel.ERROR:
return testInfo.status === 'failed'; // Only for failed tests
default:
return false;
}
}
async shouldCaptureHtmlDump(testInfo: TestInfo): Promise<boolean> {
const options = this.getOptions();
if (!options.htmlDumps) return false;
// Additional conditions based on verbosity level
switch (this.currentLevel) {
case VerbosityLevel.DEBUG:
case VerbosityLevel.VERBOSE:
return true; // Capture all HTML dumps
case VerbosityLevel.NORMAL:
return testInfo.status !== 'passed'; // Only for non-passing tests
case VerbosityLevel.ERROR:
return testInfo.status === 'failed'; // Only for failed tests
default:
return false;
}
}
shouldCapturePerformanceMetrics(): boolean {
return this.getOptions().performanceMetrics;
}
private async logToFile(testInfo: TestInfo, message: string): Promise<void> {
const logDir = path.join(testInfo.project.outputDir, 'logs');
const logFile = path.join(logDir, `${testInfo.testId}.log`);
await fs.mkdir(logDir, { recursive: true });
await fs.appendFile(logFile, message);
}
}
// Command line argument parser for verbosity
export function parseVerbosityArgs(args: string[]): VerbosityLevel {
const verbosityArg = args.find(arg =>
arg.startsWith('--verbosity=') ||
arg.startsWith('-v=')
);
if (!verbosityArg) return VerbosityLevel.NORMAL;
const value = verbosityArg.split('=')[1].toUpperCase();
const level = VerbosityLevel[value as keyof typeof VerbosityLevel];
return typeof level === 'number' ? level : VerbosityLevel.NORMAL;
}