Files
wehub-resource-sync 7a0da7932b
OSV-Scanner (Scheduled) / scan-scheduled (push) Failing after 0s
Create Release / test-gate (push) Has been cancelled
Create Release / release-gate (push) Has been cancelled
Create Release / ci-gate (push) Has been cancelled
Create Release / version-check (push) Has been cancelled
Create Release / e2e-test-gate (push) Has been cancelled
Create Release / responsive-test-gate (push) Has been cancelled
Create Release / compat-test-gate (push) Has been cancelled
Create Release / compose-integration-gate (push) Has been cancelled
Create Release / vulture-gate (push) Has been cancelled
Create Release / build (push) Has been cancelled
Create Release / provenance (push) Has been cancelled
Create Release / prerelease-docker (push) Has been cancelled
Create Release / publish-docker (push) Has been cancelled
Create Release / create-release (push) Has been cancelled
Create Release / cleanup-changelog (push) Has been cancelled
Create Release / trigger-pypi (push) Has been cancelled
Create Release / monitor-pypi (push) Has been cancelled
Create Release / Clean up orphan prerelease tags and signatures (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-form] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-metrics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-workflow] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-core] (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [history-news] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [library] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [link-analytics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-core] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-lifecycle] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [error-benchmark] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) (push) Has been cancelled
Docker Tests (Consolidated) / Accessibility Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Unit Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Example Tests (push) Has been cancelled
Docker Tests (Consolidated) / Production Image Smoke Test (push) Has been cancelled
Docker Tests (Consolidated) / Infrastructure Tests (push) Has been cancelled
OSSF Scorecard / OSSF Security Scorecard Analysis (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [mobile] (push) Has been cancelled
Backwards Compatibility / Verify Encryption Constants (push) Has been cancelled
Backwards Compatibility / PyPI Version Compatibility (push) Has been cancelled
Backwards Compatibility / Database Migration Tests (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Docker Tests (Consolidated) / detect-changes (push) Has been cancelled
Docker Tests (Consolidated) / Build Test Image (push) Has been cancelled
Docker Tests (Consolidated) / All Pytest Tests + Coverage (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [accessibility] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [api-crud] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-login] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-register] (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:08:55 +08:00

315 lines
9.0 KiB
JavaScript

const { spawn } = require('child_process');
const path = require('path');
const fs = require('fs');
// Test configuration
const TEST_TIMEOUT = 300000; // 5 minutes per test
// Colors for console output
const colors = {
reset: '\x1b[0m',
bright: '\x1b[1m',
green: '\x1b[32m',
red: '\x1b[31m',
yellow: '\x1b[33m',
blue: '\x1b[34m',
cyan: '\x1b[36m',
magenta: '\x1b[35m'
};
function log(message, type = 'info') {
const timestamp = new Date().toISOString().split('T')[1].split('.')[0];
const typeColors = {
'info': colors.cyan,
'success': colors.green,
'error': colors.red,
'warning': colors.yellow,
'section': colors.blue,
'test': colors.magenta
};
const color = typeColors[type] || colors.reset;
console.log(`${color}[${timestamp}] ${message}${colors.reset}`);
}
// Test files to run
const testFiles = [
// Authentication tests
'test_auth_flow.js',
'test_simple_auth.js',
// Core functionality tests
'test_simple_research.js',
'test_history_page.js',
'test_research_details.js',
'test_settings_persistence.js',
'test_research_cancellation.js',
// Settings tests
'test_settings_page.js',
'test_api_key_settings.js',
// Research tests
'test_research_form.js',
'test_research_submit.js',
// Navigation tests
'test_full_navigation.js',
// Metrics tests
'test_simple_metrics.js',
'test_metrics_display.js',
// Complete workflow tests
'test_complete_workflow.js'
];
// Test results
const results = {
total: testFiles.length,
passed: 0,
failed: 0,
skipped: 0,
details: []
};
async function runTest(testFile) {
return new Promise((resolve) => {
const testPath = path.join(__dirname, testFile);
// Check if test file exists
if (!fs.existsSync(testPath)) {
log(`⚠️ Test file not found: ${testFile}`, 'warning');
results.skipped++;
results.details.push({
name: testFile,
status: 'skipped',
reason: 'File not found'
});
resolve();
return;
}
log(`\n${'='.repeat(60)}`, 'section');
log(`🧪 Running test: ${testFile}`, 'test');
log(`${'='.repeat(60)}`, 'section');
const startTime = Date.now();
const testProcess = spawn('node', [testPath], {
cwd: __dirname,
env: { ...process.env, NODE_ENV: 'test' }
});
let output = '';
let errorOutput = '';
// Capture stdout
testProcess.stdout.on('data', (data) => {
const text = data.toString();
process.stdout.write(text);
output += text;
});
// Capture stderr
testProcess.stderr.on('data', (data) => {
const text = data.toString();
process.stderr.write(text);
errorOutput += text;
});
// Set timeout
const timeout = setTimeout(() => {
log(`⏱️ Test timeout after ${TEST_TIMEOUT/1000} seconds`, 'error');
testProcess.kill('SIGTERM');
}, TEST_TIMEOUT);
// Handle test completion
testProcess.on('close', (code) => {
clearTimeout(timeout);
const duration = ((Date.now() - startTime) / 1000).toFixed(2);
if (code === 0) {
log(`✅ Test passed (${duration}s)`, 'success');
results.passed++;
results.details.push({
name: testFile,
status: 'passed',
duration,
output
});
} else {
log(`❌ Test failed with code ${code} (${duration}s)`, 'error');
results.failed++;
results.details.push({
name: testFile,
status: 'failed',
duration,
code,
output,
error: errorOutput
});
}
resolve();
});
// Handle errors
testProcess.on('error', (error) => {
clearTimeout(timeout);
log(`❌ Failed to run test: ${error.message}`, 'error');
results.failed++;
results.details.push({
name: testFile,
status: 'failed',
error: error.message
});
resolve();
});
});
}
async function ensureScreenshotsDir() {
const screenshotsDir = path.join(__dirname, 'screenshots');
if (!fs.existsSync(screenshotsDir)) {
fs.mkdirSync(screenshotsDir, { recursive: true });
log('📁 Created screenshots directory', 'info');
}
}
async function generateReport() {
log('\n' + '='.repeat(60), 'section');
log('📊 TEST SUMMARY REPORT', 'section');
log('='.repeat(60), 'section');
const successRate = results.total > 0 ?
((results.passed / results.total) * 100).toFixed(1) : 0;
log(`\nTotal Tests: ${results.total}`, 'info');
log(`✅ Passed: ${results.passed}`, 'success');
log(`❌ Failed: ${results.failed}`, results.failed > 0 ? 'error' : 'info');
log(`⏭️ Skipped: ${results.skipped}`, 'warning');
log(`📈 Success Rate: ${successRate}%`,
successRate >= 80 ? 'success' : successRate >= 50 ? 'warning' : 'error');
// Detailed results
log('\n📋 Detailed Results:', 'section');
results.details.forEach((test, index) => {
const icon = test.status === 'passed' ? '✅' :
test.status === 'failed' ? '❌' : '⏭️';
log(`\n${index + 1}. ${icon} ${test.name}`, 'info');
if (test.duration) {
log(` Duration: ${test.duration}s`, 'info');
}
if (test.status === 'failed' && test.error) {
log(` Error: ${test.error}`, 'error');
}
if (test.status === 'skipped' && test.reason) {
log(` Reason: ${test.reason}`, 'warning');
}
});
// Save report to file
const reportPath = path.join(__dirname, 'test_report.json');
fs.writeFileSync(reportPath, JSON.stringify(results, null, 2));
log(`\n💾 Test report saved to: ${reportPath}`, 'info');
// List screenshots
const screenshotsDir = path.join(__dirname, 'screenshots');
if (fs.existsSync(screenshotsDir)) {
const screenshots = fs.readdirSync(screenshotsDir);
if (screenshots.length > 0) {
log('\n📸 Screenshots captured:', 'section');
screenshots.forEach(file => {
log(` - ${file}`, 'info');
});
}
}
}
async function checkServerRunning() {
const http = require('http');
return new Promise((resolve) => {
const options = {
hostname: '127.0.0.1',
port: 5000,
path: '/health',
method: 'GET',
timeout: 5000
};
const req = http.request(options, (res) => {
resolve(res.statusCode === 200 || res.statusCode === 404);
});
req.on('error', () => {
resolve(false);
});
req.on('timeout', () => {
req.destroy();
resolve(false);
});
req.end();
});
}
async function runAllTests() {
log('🚀 Starting LDR UI Test Suite', 'section');
log(`📅 Date: ${new Date().toLocaleString()}`, 'info');
// Ensure screenshots directory exists
await ensureScreenshotsDir();
// Check if server is running
log('\n🔍 Checking if LDR server is running...', 'info');
const serverRunning = await checkServerRunning();
if (!serverRunning) {
log('❌ LDR server is not running on http://127.0.0.1:5000', 'error');
log('💡 Please start the server with: ./scripts/test_with_restart.sh', 'info');
process.exit(1);
}
log('✅ Server is running', 'success');
// Run tests sequentially
const startTime = Date.now();
for (const testFile of testFiles) {
await runTest(testFile);
}
const totalDuration = ((Date.now() - startTime) / 1000).toFixed(2);
log(`\n⏱️ Total test duration: ${totalDuration}s`, 'info');
// Generate report
await generateReport();
// Exit with appropriate code
if (results.failed > 0) {
log('\n❌ Some tests failed. Please check the results above.', 'error');
process.exit(1);
} else if (results.passed === results.total) {
log('\n🎉 All tests passed!', 'success');
process.exit(0);
} else {
log('\n⚠️ Some tests were skipped. Please check the results above.', 'warning');
process.exit(0);
}
}
// Handle interruptions gracefully
process.on('SIGINT', () => {
log('\n\n🛑 Test suite interrupted by user', 'warning');
generateReport().then(() => {
process.exit(1);
});
});
// Run all tests
runAllTests().catch(error => {
log(`\n❌ Test suite error: ${error.message}`, 'error');
process.exit(1);
});