95 lines
3.8 KiB
JavaScript
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;
|