Reporter API¶
The Reporter is responsible for generating and managing test reports, supporting HTML and JSON formats, and providing failure analysis and dashboard statistics functionality.
Reporter Class¶
Constructor¶
constructor(
outputDir?: string,
storage?: StorageProvider,
diagnosisService?: DiagnosisService,
flakyManager?: FlakyTestManager
)
| Parameter | Type | Default | Description |
|---|---|---|---|
outputDir |
string |
'./reports' |
Report output directory |
storage |
StorageProvider |
Default storage provider | Storage abstraction layer |
diagnosisService |
DiagnosisService |
null |
AI diagnosis service for failure analysis |
flakyManager |
FlakyTestManager |
undefined |
Flaky test manager for root cause analysis |
During construction, the output directory is automatically created, and an in-memory cache is initialized (maximum cache size is determined by CACHE_CONFIG.MAX_REPORT_CACHE_SIZE).
generateReport(runResult)¶
Generates a test report, outputting JSON and HTML files.
Parameters:
| Parameter | Type | Description |
|---|---|---|
runResult |
RunResult |
Test run result |
Return Value: HTML report file path (string)
Behavior:
- Writes the run result to
{outputDir}/{runId}.json - If HTML report does not exist, generates
{outputDir}/{runId}.htmlfrom template - Adds the result to in-memory cache
- Returns the HTML report path
analyzeFailures(runResult)¶
Analyzes failed tests in the run result and returns a list of failure analyses.
Parameters:
| Parameter | Type | Description |
|---|---|---|
runResult |
RunResult |
Test run result |
Return Value: FailureAnalysis[]
Behavior:
- Iterates through all tests with
failedstatus in all suites - For each failed test, performs error classification (
categorizeError) and generates suggestions (generateSuggestions) - If
diagnosisServiceis configured and enabled, performs AI diagnosis for each failure analysis - AI diagnosis incorporates root cause analysis data from
flakyManager - Diagnosis results are written back to the corresponding flaky test records in
flakyManager
generateDashboard()¶
Generates dashboard statistics.
Return Value: DashboardStats
interface DashboardStats {
totalRuns: number;
totalTests: number;
passRate: number;
avgDuration: number;
flakyTests: number;
quarantinedTests: number;
recentRuns: RunResult[];
}
getReport(reportId)¶
Retrieves the report for a specific run.
deleteReport(reportId)¶
Deletes the report for a specific run (including JSON, HTML, and Playwright HTML report directory).
deleteAllReports()¶
Deletes all reports.
Return Value: Number of deleted reports
getAllReports()¶
Retrieves all reports.
clearCache()¶
Clears the in-memory cache, forcing the next getAllReports call to reload from the file system.
createPendingReport(runId, version)¶
Creates a pending report (for real-time update scenarios).
Behavior: Creates an initial RunResult with status 'running', writes it to a JSON file, and adds it to the cache.
updatePendingReport(runId, testResult, suiteName)¶
Updates the test result in a pending report.
Behavior:
- Finds the pending report; if not found, skips
- Finds or creates the corresponding suite
- If the test already exists, updates it; otherwise, adds the new test
- Updates suite and report statistics
finalizePendingReport(runId, status)¶
Finalizes the pending report, sets the final status, and generates the complete report.
async finalizePendingReport(
runId: string,
status: 'success' | 'failed' | 'cancelled'
): Promise<string>
Behavior:
- Sets the report status,
endTime, andduration - Calls
generateReportto generate the complete report - Updates the JSON file
- Removes from pending reports
- Returns the HTML report path
getPendingReport(runId)¶
Retrieves a pending report.
hasPendingReport(runId)¶
Checks if a pending report exists.
updateTestResult(runId, testId, newResult)¶
Updates the result of a specific test in a report (for manual rerun scenarios).
Behavior:
- Finds the report and corresponding test
- Saves the old result to
runHistory - Increments the
manualRerunscount - Replaces the old result with the new result (preserving
id,retries,manualReruns,runHistory) - Updates suite and report statistics
- Writes to JSON file
- Returns whether successful
JSONReporter Class¶
Inherits from Reporter, provides JSON format report generation.
generateJSONReport(runResult)¶
Generates a JSON format report string.
Type Definitions¶
FailureAnalysis¶
interface FailureAnalysis {
testId: string;
title: string;
failureReason: string;
category: 'assertion' | 'timeout' | 'network' | 'selector' | 'frame' | 'auth' | 'unknown';
suggestions: string[];
occurrences: number;
lastOccurrence: number;
firstOccurrence?: number;
filePath?: string;
lineNumber?: number;
stackTrace?: string;
browser?: string;
aiDiagnosis?: AIDiagnosis;
}
FailureAnalysisSummary¶
interface FailureAnalysisSummary {
total: number;
persistent: number;
emerging: number;
firstTimeFailures: number;
byClassification: Record<string, number>;
}
ReportFailureSummary¶
interface ReportFailureSummary {
total: number;
persistent: number;
emerging: number;
firstTimeFailures: number;
byCategory: Record<string, number>;
}
ReportFailureItem¶
interface ReportFailureItem {
testId: string;
title: string;
error: string;
category: string;
failureCount: number;
lastFailureTime: number;
firstFailureTime: number;
filePath?: string;
lineNumber?: number;
suggestions: string[];
}
FailureAnalysisResult¶
Union type, can be a failure analysis summary, a list of flaky tests, or a list of immediate failures.
ReportFailureResult¶
Union type, can be a report failure summary or a list of report failure items.
ImmediateFailure¶
interface ImmediateFailure {
testId: string;
title: string;
error?: string;
status: string;
timestamp: number;
duration?: number;
}
DashboardStats¶
interface DashboardStats {
totalRuns: number;
totalTests: number;
passRate: number;
avgDuration: number;
flakyTests: number;
quarantinedTests: number;
recentRuns: RunResult[];
}
AIDiagnosis¶
interface AIDiagnosis {
summary: string;
rootCause: string;
suggestions: string[];
confidence: number;
model: string;
timestamp: number;
category: 'timeout' | 'selector' | 'assertion' | 'network' | 'frame' | 'auth' | 'unknown';
codeDiffs?: CodeDiff[];
docLinks?: DocLink[];
contextUsed: ContextUsed;
reasoningSteps?: ReasoningStep[];
calibratedConfidence: number;
analysisMode: 'agent' | 'single' | 'fallback';
relatedFailures?: string[];
}
CodeDiff¶
DocLink¶
ContextUsed¶
interface ContextUsed {
sourceCode: boolean;
screenshot: boolean;
consoleLogs: boolean;
stackTrace: boolean;
historyData: boolean;
environmentInfo: boolean;
}
ReasoningStep¶
interface ReasoningStep {
step: number;
tool?: string;
input?: string;
output?: string;
thought: string;
}
Examples¶
Basic Usage¶
import { Reporter } from 'yuantest-playwright';
const reporter = new Reporter('./reports');
// Generate report
const reportPath = await reporter.generateReport(result);
console.log(`Report generated: ${reportPath}`);
Failure Analysis¶
const analysis = await reporter.analyzeFailures(result);
analysis.forEach((failure) => {
console.log(`[${failure.category}] ${failure.title}`);
console.log(` Reason: ${failure.failureReason}`);
console.log(` Occurrences: ${failure.occurrences}`);
failure.suggestions.forEach((s) => console.log(` Suggestion: ${s}`));
if (failure.aiDiagnosis) {
console.log(` AI Root Cause: ${failure.aiDiagnosis.rootCause}`);
console.log(` AI Confidence: ${failure.aiDiagnosis.confidence}`);
}
});
Dashboard Statistics¶
const dashboard = await reporter.generateDashboard();
console.log(`Total runs: ${dashboard.totalRuns}`);
console.log(`Pass rate: ${dashboard.passRate.toFixed(1)}%`);
console.log(`Average duration: ${dashboard.avgDuration.toFixed(0)}ms`);
console.log(`Flaky tests: ${dashboard.flakyTests}`);
Viewing Historical Reports¶
const reports = await reporter.getAllReports();
reports.forEach((report) => {
console.log(`${report.id}: ${report.passed}/${report.totalTests} passed`);
});
const report = await reporter.getReport('run_20240101_120000_abc123');
if (report) {
console.log(`Run: ${report.id}`);
console.log(`Duration: ${report.duration}ms`);
}
Real-time Reporting (Pending Reports)¶
// Create pending report
const pendingReport = await reporter.createPendingReport('run_123', '1.0.0');
// Update as tests execute
await reporter.updatePendingReport('run_123', testResult1, 'Login Suite');
await reporter.updatePendingReport('run_123', testResult2, 'Login Suite');
// Finalize report
const htmlPath = await reporter.finalizePendingReport('run_123', 'success');
console.log(`Final report: ${htmlPath}`);
Manual Rerun Update¶
const updated = await reporter.updateTestResult('run_123', 'test_456', newTestResult);
if (updated) {
console.log('Test result updated successfully');
}
Deleting Reports¶
// Delete a single report
const deleted = await reporter.deleteReport('run_123');
console.log(`Deleted: ${deleted}`);
// Delete all reports
const count = await reporter.deleteAllReports();
console.log(`Deleted ${count} reports`);