first commit
This commit is contained in:
@@ -0,0 +1,153 @@
|
||||
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);
|
||||
Reference in New Issue
Block a user