upskill-event-manager/wordpress-dev/tests/e2e/utils/logParser.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

106 lines
No EOL
3.4 KiB
TypeScript

import { readFile } from 'fs/promises';
import { Client, SFTPWrapper } from 'ssh2';
import { STAGING_CONFIG } from '../../../playwright.config';
export interface LogEntry {
timestamp: string;
level: 'INFO' | 'WARNING' | 'ERROR';
component: string;
message: string;
context?: Record<string, unknown>;
}
export class LogParser {
private sshConfig = {
host: STAGING_CONFIG.ip,
username: STAGING_CONFIG.sshUser,
path: STAGING_CONFIG.path
};
async parseLogFile(path: string): Promise<LogEntry[]> {
const logContent = await this.fetchLogContent(path);
return this.parseLogContent(logContent);
}
async findRelatedEntries(entry: LogEntry): Promise<LogEntry[]> {
const allLogs = await this.parseLogFile('wordpress.log');
return allLogs.filter(log =>
log.component === entry.component &&
Math.abs(new Date(log.timestamp).getTime() - new Date(entry.timestamp).getTime()) < 5000
);
}
async validateLogSequence(entries: LogEntry[], expectedFlow: string[]): Promise<boolean> {
let currentIndex = 0;
for (const expected of expectedFlow) {
let found = false;
while (currentIndex < entries.length) {
if (entries[currentIndex].message.includes(expected)) {
found = true;
break;
}
currentIndex++;
}
if (!found) return false;
}
return true;
}
private async fetchLogContent(path: string): Promise<string> {
const conn = new Client();
return new Promise<string>((resolve, reject) => {
conn.on('ready', () => {
conn.sftp((err: Error | undefined, sftp: SFTPWrapper) => {
if (err) {
reject(err);
return;
}
const remotePath = `${this.sshConfig.path}/wp-content/debug.log`;
sftp.readFile(remotePath, (err: Error | undefined, data: Buffer) => {
if (err) {
reject(err);
return;
}
resolve(data.toString());
conn.end();
});
});
}).connect(this.sshConfig);
});
}
private parseLogContent(content: string): LogEntry[] {
const entries: LogEntry[] = [];
content.split('\n')
.filter(line => line.trim())
.forEach(line => {
const match = line.match(/\[(.*?)\]\s+(\w+):\s+\[(\w+)\]\s+(.*)/);
if (!match) return;
entries.push({
timestamp: match[1],
level: match[2] as 'INFO' | 'WARNING' | 'ERROR',
component: match[3],
message: match[4],
context: this.extractContext(match[4])
});
});
return entries;
}
private extractContext(message: string): Record<string, unknown> {
const contextMatch = message.match(/\{.*\}/);
if (!contextMatch) return {};
try {
return JSON.parse(contextMatch[0]);
} catch {
return {};
}
}
}