Files
2026-06-24 20:05:36 +05:30

95 lines
3.8 KiB
JavaScript

const fs = require('fs');
const path = require('path');
const { spawnSync } = require('child_process');
function runPython(args, inputObj) {
const result = spawnSync('python3', ['scripts/sqlite_db.py', ...args], {
cwd: process.cwd(),
input: inputObj ? JSON.stringify(inputObj) : undefined,
encoding: 'utf8',
env: process.env,
maxBuffer: 1024 * 1024 * 10,
});
if (result.status !== 0) {
const msg = result.stderr || result.stdout || 'Unknown sqlite_db.py error';
throw new Error(msg);
}
const out = (result.stdout || '').trim();
return out ? JSON.parse(out) : {};
}
class SqliteReporter {
constructor(options = {}) {
this.dbPath = options.dbPath || process.env.SQLITE_RESULTS_DB || 'results/uat_vapt_results.sqlite';
this.runName = options.runName || process.env.TEST_RUN_NAME || `Run ${new Date().toISOString()}`;
this.runId = null;
}
onBegin(config, suite) {
fs.mkdirSync(path.dirname(this.dbPath), { recursive: true });
runPython(['--db', this.dbPath, 'init']);
const matrixPath = process.env.TEST_MATRIX_JSON || 'data/generated-test-matrix.json';
if (fs.existsSync(matrixPath)) {
runPython(['--db', this.dbPath, '--matrix', matrixPath, 'import-cases']);
}
const started = runPython(['--db', this.dbPath, '--run-name', this.runName, '--base-url', process.env.BASE_URL || '', 'begin-run']);
this.runId = started.run_id;
console.log(`SQLite reporter writing to ${this.dbPath}; run_id=${this.runId}`);
}
extractVariantId(test) {
const titlePath = test.titlePath ? test.titlePath() : [test.title];
const fullTitle = titlePath.join(' ');
const bracket = fullTitle.match(/\[([^\]]+)\]/);
if (bracket) return bracket[1];
const fallback = fullTitle.match(/((?:V25-)?[A-Z][A-Z0-9]*(?:-[A-Z0-9]+)+)/);
return fallback ? fallback[1] : '';
}
onTestEnd(test, result) {
const location = test.location || {};
const attachments = (result.attachments || []).map(a => ({
name: a.name || '',
contentType: a.contentType || '',
path: a.path || '',
}));
const record = {
run_id: this.runId,
variant_id: this.extractVariantId(test),
title: test.title,
title_path: test.titlePath ? test.titlePath() : [test.title],
project_name: test.parent && test.parent.project ? (test.parent.project()?.name || '') : '',
location,
status: result.status,
expected_status: test.expectedStatus,
duration_ms: result.duration || 0,
retry: result.retry || 0,
error: result.error ? { message: result.error.message || '', stack: result.error.stack || '' } : null,
stdout: (result.stdout || []).map(x => Buffer.isBuffer(x) ? x.toString('utf8') : String(x)).join('\n'),
stderr: (result.stderr || []).map(x => Buffer.isBuffer(x) ? x.toString('utf8') : String(x)).join('\n'),
attachments,
started_at: result.startTime ? result.startTime.toISOString() : null,
finished_at: new Date().toISOString(),
};
try {
runPython(['--db', this.dbPath, 'record-result'], record);
} catch (e) {
console.error('Failed to record SQLite test result:', e.message);
}
}
onEnd(result) {
if (!this.runId) return;
try {
runPython(['--db', this.dbPath, '--run-id', String(this.runId), '--status', result.status || 'completed', 'finish-run']);
runPython(['--db', this.dbPath, '--run-id', String(this.runId), '--output', 'results/merged-results.json', 'export-json']);
runPython(['--db', this.dbPath, '--run-id', String(this.runId), '--output', 'results/UAT_VAPT_SQLite_Export.xlsx', 'export-xlsx']);
console.log(`SQLite run ${this.runId} finished and exported.`);
} catch (e) {
console.error('Failed to finish/export SQLite run:', e.message);
}
}
}
module.exports = SqliteReporter;