154 lines
4.5 KiB
TypeScript
154 lines
4.5 KiB
TypeScript
import type { FeatureTestStatus, ScenarioTestResult } from '../src/types/gherkin';
|
|
|
|
interface CucumberScenario {
|
|
id: string;
|
|
name: string;
|
|
steps: Array<{
|
|
result: {
|
|
status: 'passed' | 'failed' | 'skipped' | 'pending' | 'undefined';
|
|
duration?: number;
|
|
error_message?: string;
|
|
};
|
|
}>;
|
|
}
|
|
|
|
interface CucumberFeature {
|
|
id: string;
|
|
uri: string;
|
|
name: string;
|
|
elements: CucumberScenario[];
|
|
}
|
|
|
|
export async function parseTestResults(): Promise<Map<string, FeatureTestStatus>> {
|
|
const reportPath = 'reports/cucumber-report.json';
|
|
const file = Bun.file(reportPath);
|
|
|
|
if (!await file.exists()) {
|
|
console.log('No test report found at', reportPath);
|
|
return new Map();
|
|
}
|
|
|
|
const content = await file.text();
|
|
const features: CucumberFeature[] = JSON.parse(content);
|
|
const results = new Map<string, FeatureTestStatus>();
|
|
|
|
for (const feature of features) {
|
|
// Extract feature ID from URI (e.g., features/user/us-9-visualiser-photo.feature -> us-9)
|
|
const match = feature.uri.match(/us-(\d+)/i);
|
|
const featureId = match ? `us-${match[1]}` : feature.id;
|
|
|
|
const scenarios = feature.elements.filter(el => el.name); // Filter out Background
|
|
let passed = 0;
|
|
let failed = 0;
|
|
let skipped = 0;
|
|
const scenarioResults: ScenarioTestResult[] = [];
|
|
|
|
for (const scenario of scenarios) {
|
|
const { status: scenarioStatus, errorMessage } = getScenarioStatusAndError(scenario);
|
|
if (scenarioStatus === 'passed') passed++;
|
|
else if (scenarioStatus === 'failed') failed++;
|
|
else skipped++;
|
|
|
|
scenarioResults.push({
|
|
name: scenario.name,
|
|
status: scenarioStatus,
|
|
errorMessage,
|
|
});
|
|
}
|
|
|
|
results.set(featureId, {
|
|
featureId,
|
|
totalScenarios: scenarios.length,
|
|
passed,
|
|
failed,
|
|
skipped,
|
|
lastRun: new Date(),
|
|
scenarios: scenarioResults,
|
|
});
|
|
}
|
|
|
|
return results;
|
|
}
|
|
|
|
function getScenarioStatusAndError(scenario: CucumberScenario): { status: 'passed' | 'failed' | 'skipped'; errorMessage?: string } {
|
|
for (const step of scenario.steps) {
|
|
if (step.result.status === 'failed') {
|
|
return { status: 'failed', errorMessage: step.result.error_message };
|
|
}
|
|
if (step.result.status === 'skipped' || step.result.status === 'pending' || step.result.status === 'undefined') {
|
|
return { status: 'skipped' };
|
|
}
|
|
}
|
|
return { status: 'passed' };
|
|
}
|
|
|
|
// Generate TypeScript file with test results
|
|
async function generateTestResultsFile() {
|
|
const results = await parseTestResults();
|
|
|
|
const resultsArray = Array.from(results.entries()).map(([id, status]) => ({
|
|
...status,
|
|
lastRun: status.lastRun?.toISOString(),
|
|
}));
|
|
|
|
const output = `// Auto-generated by scripts/parse-test-results.ts
|
|
// Do not edit manually - run "bun run test:results" to regenerate
|
|
import type { FeatureTestStatus, ScenarioTestResult } from '../types/gherkin';
|
|
|
|
interface RawFeatureTestStatus {
|
|
featureId: string;
|
|
totalScenarios: number;
|
|
passed: number;
|
|
failed: number;
|
|
skipped: number;
|
|
lastRun?: string;
|
|
scenarios?: ScenarioTestResult[];
|
|
}
|
|
|
|
const rawResults: RawFeatureTestStatus[] = ${JSON.stringify(resultsArray, null, 2)};
|
|
|
|
export const testResults: Map<string, FeatureTestStatus> = new Map(
|
|
rawResults.map(r => [r.featureId, { ...r, lastRun: r.lastRun ? new Date(r.lastRun) : undefined }])
|
|
);
|
|
|
|
export function getTestStatus(featureId: string): FeatureTestStatus | undefined {
|
|
return testResults.get(featureId);
|
|
}
|
|
|
|
export function getScenarioResults(featureId: string): ScenarioTestResult[] {
|
|
return testResults.get(featureId)?.scenarios ?? [];
|
|
}
|
|
|
|
export function getAllTestResults(): FeatureTestStatus[] {
|
|
return Array.from(testResults.values());
|
|
}
|
|
|
|
export function getTestSummary() {
|
|
const results = getAllTestResults();
|
|
const firstResult = results[0];
|
|
return {
|
|
totalFeatures: results.length,
|
|
totalScenarios: results.reduce((acc, r) => acc + r.totalScenarios, 0),
|
|
passed: results.reduce((acc, r) => acc + r.passed, 0),
|
|
failed: results.reduce((acc, r) => acc + r.failed, 0),
|
|
skipped: results.reduce((acc, r) => acc + r.skipped, 0),
|
|
lastRun: firstResult?.lastRun,
|
|
};
|
|
}
|
|
`;
|
|
|
|
await Bun.write('src/data/testResults.ts', output);
|
|
console.log(`Generated test results for ${results.size} features`);
|
|
|
|
// Print summary
|
|
let totalPassed = 0, totalFailed = 0, totalSkipped = 0;
|
|
results.forEach(r => {
|
|
totalPassed += r.passed;
|
|
totalFailed += r.failed;
|
|
totalSkipped += r.skipped;
|
|
});
|
|
console.log(`Summary: ${totalPassed} passed, ${totalFailed} failed, ${totalSkipped} skipped`);
|
|
}
|
|
|
|
generateTestResultsFile().catch(console.error);
|