agentic-qe
Version:
Agentic Quality Engineering Fleet System - AI-driven quality management platform
243 lines • 7.96 kB
JavaScript
;
/**
* Trace Command
* Traces test execution flow with timing and call stack
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.traceExecution = void 0;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
/**
* Trace test execution flow
*/
async function traceExecution(options) {
try {
const startTime = Date.now();
const steps = [];
// Simulate tracing test execution
// In real implementation, this would hook into the test runner
steps.push(await traceTestSetup(options));
steps.push(await traceTestExecution(options));
steps.push(await traceTestTeardown(options));
// Filter by minimum duration if specified
let filteredSteps = steps;
if (options.minDuration !== undefined) {
filteredSteps = filterStepsByDuration(steps, options.minDuration);
}
// Highlight slow operations if requested
if (options.highlightSlow) {
markSlowSteps(filteredSteps);
}
const totalDuration = Date.now() - startTime;
const trace = {
testFile: options.testFile,
totalDuration,
steps: filteredSteps,
};
// Include call stack if requested
if (options.includeCallStack) {
trace.callStack = captureCallStack();
}
// Export trace if requested
let exportPath;
if (options.export) {
const outputDir = options.outputDir || path.join(process.cwd(), '.swarm', 'reports');
fs.mkdirSync(outputDir, { recursive: true });
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
if (options.export === 'json') {
exportPath = path.join(outputDir, `trace-${timestamp}.json`);
fs.writeFileSync(exportPath, JSON.stringify({ trace }, null, 2));
}
else if (options.export === 'chrome-devtools') {
exportPath = path.join(outputDir, `trace-${timestamp}.json`);
const chromeTrace = convertToChromeDeveloperTools(trace);
fs.writeFileSync(exportPath, JSON.stringify(chromeTrace, null, 2));
}
}
return {
success: true,
trace,
exportPath,
};
}
catch (error) {
return {
success: false,
trace: {
testFile: options.testFile,
totalDuration: 0,
steps: [],
},
error: error.message,
};
}
}
exports.traceExecution = traceExecution;
async function traceTestSetup(options) {
const startTime = Date.now();
// Simulate test setup
await new Promise(resolve => setTimeout(resolve, 10));
const endTime = Date.now();
return {
name: 'beforeEach',
type: 'beforeEach',
startTime,
endTime,
duration: options.measureTiming ? endTime - startTime : undefined,
};
}
async function traceTestExecution(options) {
const startTime = Date.now();
// Simulate test execution with nested calls
const children = [];
// Function call 1
const fn1Start = Date.now();
await new Promise(resolve => setTimeout(resolve, 20));
const fn1End = Date.now();
children.push({
name: 'calculateResult',
type: 'function',
startTime: fn1Start,
endTime: fn1End,
duration: options.measureTiming ? fn1End - fn1Start : undefined,
});
// Async operation
const asyncStart = Date.now();
await new Promise(resolve => setTimeout(resolve, 50));
const asyncEnd = Date.now();
children.push({
name: 'fetchData',
type: 'async',
startTime: asyncStart,
endTime: asyncEnd,
duration: options.measureTiming ? asyncEnd - asyncStart : undefined,
});
// Function call 2
const fn2Start = Date.now();
await new Promise(resolve => setTimeout(resolve, 15));
const fn2End = Date.now();
children.push({
name: 'validateResult',
type: 'function',
startTime: fn2Start,
endTime: fn2End,
duration: options.measureTiming ? fn2End - fn2Start : undefined,
});
const endTime = Date.now();
return {
name: 'test: should complete successfully',
type: 'test',
startTime,
endTime,
duration: options.measureTiming ? endTime - startTime : undefined,
children,
};
}
async function traceTestTeardown(options) {
const startTime = Date.now();
// Simulate test teardown
await new Promise(resolve => setTimeout(resolve, 5));
const endTime = Date.now();
return {
name: 'afterEach',
type: 'afterEach',
startTime,
endTime,
duration: options.measureTiming ? endTime - startTime : undefined,
};
}
function filterStepsByDuration(steps, minDuration) {
return steps
.filter(step => step.duration === undefined || step.duration >= minDuration)
.map(step => ({
...step,
children: step.children ? filterStepsByDuration(step.children, minDuration) : undefined,
}));
}
function markSlowSteps(steps, threshold = 30) {
for (const step of steps) {
if (step.duration && step.duration > threshold) {
step.slow = true;
}
if (step.children) {
markSlowSteps(step.children, threshold);
}
}
}
function captureCallStack() {
const stack = new Error().stack;
if (!stack)
return [];
return stack
.split('\n')
.slice(2) // Skip Error and this function
.map(line => line.trim())
.filter(line => line.startsWith('at '));
}
function convertToChromeDeveloperTools(trace) {
const events = [];
let eventId = 0;
function addStep(step, parentId) {
const id = eventId++;
events.push({
name: step.name,
cat: step.type,
ph: 'B', // Begin
ts: step.startTime * 1000, // Convert to microseconds
pid: 1,
tid: 1,
args: {},
});
if (step.endTime) {
events.push({
name: step.name,
cat: step.type,
ph: 'E', // End
ts: step.endTime * 1000,
pid: 1,
tid: 1,
args: {},
});
}
if (step.children) {
for (const child of step.children) {
addStep(child, id);
}
}
}
for (const step of trace.steps) {
addStep(step);
}
return {
traceEvents: events,
displayTimeUnit: 'ms',
otherData: {
testFile: trace.testFile,
totalDuration: trace.totalDuration,
},
};
}
//# sourceMappingURL=trace.js.map