- 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.
135 lines
No EOL
3.9 KiB
TypeScript
135 lines
No EOL
3.9 KiB
TypeScript
import { FullConfig } from '@playwright/test';
|
|
import { Client } from 'ssh2';
|
|
import { STAGING_CONFIG } from '../../playwright.config';
|
|
import * as fs from 'fs';
|
|
import * as path from 'path';
|
|
|
|
interface LogFileStats {
|
|
size: number;
|
|
lastModified: Date;
|
|
}
|
|
|
|
interface LogSummary {
|
|
testRun: {
|
|
startTime: string;
|
|
endTime: string;
|
|
logsLocation: string;
|
|
};
|
|
logFiles: {
|
|
[key: string]: LogFileStats;
|
|
};
|
|
}
|
|
|
|
async function globalTeardown(config: FullConfig) {
|
|
const testLogsDir = process.env.TEST_LOGS_DIR;
|
|
const testStartTime = process.env.TEST_START_TIME;
|
|
|
|
if (!testLogsDir || !testStartTime) {
|
|
console.warn('Warning: Test environment variables not found during teardown');
|
|
return;
|
|
}
|
|
|
|
// Create final logs directory with timestamp
|
|
const finalLogsDir = path.join(
|
|
testLogsDir,
|
|
`run-${new Date().toISOString().replace(/[:.]/g, '-')}`
|
|
);
|
|
fs.mkdirSync(finalLogsDir, { recursive: true });
|
|
|
|
// Fetch final state of logs
|
|
const conn = new Client();
|
|
|
|
try {
|
|
await new Promise<void>((resolve, reject) => {
|
|
conn.on('ready', () => {
|
|
conn.sftp((err, sftp) => {
|
|
if (err) {
|
|
reject(err);
|
|
return;
|
|
}
|
|
|
|
const logFiles = [
|
|
'debug.log',
|
|
'error.log',
|
|
'access.log'
|
|
];
|
|
|
|
let completedFiles = 0;
|
|
|
|
// Fetch all log files
|
|
logFiles.forEach(logFile => {
|
|
const remotePath = `${STAGING_CONFIG.path}/wp-content/${logFile}`;
|
|
const localPath = path.join(finalLogsDir, logFile);
|
|
|
|
sftp.fastGet(remotePath, localPath, (err) => {
|
|
if (err) {
|
|
console.warn(`Warning: Could not fetch ${logFile}:`, err);
|
|
}
|
|
|
|
completedFiles++;
|
|
if (completedFiles === logFiles.length) {
|
|
resolve();
|
|
}
|
|
});
|
|
});
|
|
});
|
|
}).connect({
|
|
host: STAGING_CONFIG.ip,
|
|
username: STAGING_CONFIG.sshUser
|
|
});
|
|
});
|
|
|
|
// Generate log summary
|
|
const summary: LogSummary = {
|
|
testRun: {
|
|
startTime: testStartTime,
|
|
endTime: new Date().toISOString(),
|
|
logsLocation: finalLogsDir
|
|
},
|
|
logFiles: {}
|
|
};
|
|
|
|
// Add log file statistics to summary
|
|
const logFiles = fs.readdirSync(finalLogsDir);
|
|
for (const file of logFiles) {
|
|
const stats = fs.statSync(path.join(finalLogsDir, file)) as fs.Stats;
|
|
summary.logFiles[file] = {
|
|
size: stats.size,
|
|
lastModified: stats.mtime
|
|
} as LogFileStats;
|
|
}
|
|
|
|
// Write summary to JSON file
|
|
fs.writeFileSync(
|
|
path.join(finalLogsDir, 'log-summary.json'),
|
|
JSON.stringify(summary, null, 2)
|
|
);
|
|
|
|
// Generate Markdown report
|
|
const markdownReport = `# Test Run Log Summary
|
|
## Run Information
|
|
- Start Time: ${summary.testRun.startTime}
|
|
- End Time: ${summary.testRun.endTime}
|
|
- Logs Location: ${summary.testRun.logsLocation}
|
|
|
|
## Log Files
|
|
${Object.entries(summary.logFiles)
|
|
.map(([file, stats]) => `### ${file}
|
|
- Size: ${stats.size} bytes
|
|
- Last Modified: ${stats.lastModified}`)
|
|
.join('\n\n')}
|
|
`;
|
|
|
|
fs.writeFileSync(
|
|
path.join(finalLogsDir, 'log-summary.md'),
|
|
markdownReport
|
|
);
|
|
|
|
} catch (error) {
|
|
console.error('Error during global teardown:', error);
|
|
} finally {
|
|
conn.end();
|
|
}
|
|
}
|
|
|
|
export default globalTeardown; |