- 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.
129 lines
No EOL
5.3 KiB
TypeScript
129 lines
No EOL
5.3 KiB
TypeScript
import { FullConfig } from '@playwright/test';
|
|
import { Client } from 'ssh2';
|
|
import { STAGING_CONFIG } from '../../playwright.config';
|
|
|
|
async function globalSetup(config: FullConfig) {
|
|
// Validate required environment variables
|
|
if (!process.env.UPSKILL_STAGING_PASS && !process.env.SSH_PRIVATE_KEY) {
|
|
throw new Error('Either UPSKILL_STAGING_PASS or SSH_PRIVATE_KEY must be set for authentication');
|
|
}
|
|
if (!STAGING_CONFIG.ip || !STAGING_CONFIG.sshUser) {
|
|
throw new Error('Missing required staging configuration: ip and sshUser must be set');
|
|
}
|
|
|
|
console.log('Starting global setup with configuration:', {
|
|
host: STAGING_CONFIG.ip,
|
|
username: STAGING_CONFIG.sshUser,
|
|
authMethod: process.env.SSH_PRIVATE_KEY ? 'key-based' : 'password'
|
|
});
|
|
|
|
// Ensure test results directory exists
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const testResultsDir = path.join(__dirname, '../../test-results');
|
|
const logsDir = path.join(testResultsDir, 'logs');
|
|
|
|
if (!fs.existsSync(testResultsDir)) {
|
|
fs.mkdirSync(testResultsDir, { recursive: true });
|
|
}
|
|
if (!fs.existsSync(logsDir)) {
|
|
fs.mkdirSync(logsDir, { recursive: true });
|
|
}
|
|
|
|
// Initialize SSH connection and fetch initial logs
|
|
const maxRetries = 3;
|
|
const retryDelay = 5000; // 5 seconds between retries
|
|
|
|
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
const conn = new Client();
|
|
|
|
try {
|
|
console.log(`SSH Connection Attempt ${attempt}/${maxRetries}`);
|
|
|
|
await new Promise<void>((resolve, reject) => {
|
|
let connectionTimeout: NodeJS.Timeout;
|
|
|
|
conn.on('ready', () => {
|
|
clearTimeout(connectionTimeout);
|
|
console.log('SSH Connection Ready');
|
|
|
|
conn.exec("echo 'SSH Connection Test Successful'", (err, stream) => {
|
|
if (err) {
|
|
console.error('SSH command execution failed:', err);
|
|
reject(err);
|
|
return;
|
|
}
|
|
|
|
stream.on('close', (code: number) => {
|
|
console.log('SSH command completed with code:', code);
|
|
|
|
conn.sftp((sftpErr, sftp) => {
|
|
if (sftpErr) {
|
|
console.error('SFTP initialization failed:', sftpErr);
|
|
reject(sftpErr);
|
|
return;
|
|
}
|
|
|
|
const remotePath = `${STAGING_CONFIG.path}/wp-content/debug.log`;
|
|
const localPath = path.join(logsDir, 'wordpress-initial.log');
|
|
|
|
sftp.fastGet(remotePath, localPath, (getErr) => {
|
|
if (getErr) {
|
|
console.warn('Warning: Could not fetch initial log state:', getErr);
|
|
} else {
|
|
console.log('Initial log state fetched successfully.');
|
|
}
|
|
resolve();
|
|
});
|
|
});
|
|
}).on('data', (data: Buffer) => {
|
|
console.log('SSH command output:', data.toString().trim());
|
|
}).stderr.on('data', (data: Buffer) => {
|
|
console.error('SSH command error:', data.toString());
|
|
});
|
|
});
|
|
});
|
|
|
|
conn.on('error', (err) => {
|
|
clearTimeout(connectionTimeout);
|
|
console.error(`SSH Connection Error (Attempt ${attempt}):`, err);
|
|
reject(err);
|
|
});
|
|
|
|
connectionTimeout = setTimeout(() => {
|
|
conn.end();
|
|
reject(new Error(`Connection timeout (Attempt ${attempt})`));
|
|
}, 20000);
|
|
|
|
conn.connect({
|
|
host: STAGING_CONFIG.ip,
|
|
username: STAGING_CONFIG.sshUser,
|
|
password: process.env.UPSKILL_STAGING_PASS,
|
|
readyTimeout: 20000,
|
|
debug: (debug) => console.log('SSH Debug:', debug)
|
|
});
|
|
});
|
|
|
|
// If we get here, connection was successful
|
|
console.log('SSH operations completed successfully');
|
|
break;
|
|
|
|
} catch (error) {
|
|
console.error(`Attempt ${attempt} failed:`, error);
|
|
conn.end();
|
|
|
|
if (attempt === maxRetries) {
|
|
throw new Error(`Failed to establish SSH connection after ${maxRetries} attempts`);
|
|
}
|
|
|
|
// Wait before next retry
|
|
await new Promise(resolve => setTimeout(resolve, retryDelay));
|
|
}
|
|
}
|
|
|
|
// Set up custom test environment variables
|
|
process.env.TEST_LOGS_DIR = logsDir;
|
|
process.env.TEST_START_TIME = new Date().toISOString();
|
|
}
|
|
|
|
export default globalSetup; |