Skip to content
ctrf-ioPublic

About

CTRF reference implementation in TypeScript

Resources

Code of conduct

Contributing

Security policy

Stars

5 stars

Watchers

1 watching

Forks

Repository files navigation

CTRF Reference Implementation TypeScript

The reference implementation in TypeScript for the Common Test Report Format (CTRF) specification.

CTRF Open Standard

CTRF is a community-driven open standard for test reporting.

By standardizing test results, reports can be validated, merged, compared, and analyzed consistently across languages and frameworks.

Note

⭐ Starring the CTRF specification repository (https://github.com/ctrf-io/ctrf) helps support the standard.

Installation

npm install ctrf

Quick Start

import { ReportBuilder, TestBuilder, validateStrict } from "ctrf";

// Build a report using the fluent API
const report = new ReportBuilder()
	.tool({ name: "jest", version: "29.0.0" })
	.addTest(
		new TestBuilder()
			.name("should add numbers")
			.status("passed")
			.duration(150)
			.build(),
	)
	.addTest(
		new TestBuilder()
			.name("should handle errors")
			.status("failed")
			.duration(200)
			.message("Expected 5 but got 4")
			.build(),
	)
	.build();

// Validate the report
validateStrict(report);

API Reference

📚 Full API Documentation: API Reference

Types

Full TypeScript types are provided for all CTRF entities.

import type { CTRFReport, Test } from "ctrf";

const report: CTRFReport = {
	/* ... */
};
const test: Test = {
	/* ... */
};

Validation

import {
	isValid,
	validate,
	validateStrict,
	isCTRFReport,
	ValidationError,
} from "ctrf";

// Quick validation (returns boolean)
if (isValid(report)) {
	console.log("Report is valid");
}

// Detailed validation (returns ValidationResult)
const result = validate(report);
if (!result.valid) {
	result.errors?.forEach((err) => console.error(err.message));
}

// Validate against a published historical schema
const historicalResult = validate(report, { specVersion: "0.0.2" });

// `latest` is an alias for the current published specification
validateStrict(report, { specVersion: "latest" });

// Strict validation (throws on invalid)
try {
	validateStrict(report);
} catch (error) {
	if (error instanceof ValidationError) {
		console.error("Invalid report:", error.errors);
	}
}

// Type guards
if (isCTRFReport(data)) {
	// data is typed as CTRFReport
}

Building Reports

import { ReportBuilder, TestBuilder } from "ctrf";

// ReportBuilder - fluent API for constructing reports
const report = new ReportBuilder()
	.runId("run-2026-08-13")
	.tool({ name: "vitest", version: "1.0.0" })
	.environment({ osPlatform: "linux", shardId: "shard-1-of-4" })
	.addTest(/* ... */)
	.build();

// TestBuilder - fluent API for constructing tests
const test = new TestBuilder()
	.testId("authentication/login")
	.executionId("execution-123")
	.attemptId("attempt-1")
	.name("User login test")
	.status("passed")
	.duration(1500)
	.suite(["Authentication", "Login"])
	.tags(["smoke", "critical"])
	.filePath("tests/auth/login.test.ts")
	.browser("chrome")
	.build();

Retry Histories

retryAttempts is the ordered history of attempts completed before the final attempt represented by the test object. It includes the initial attempt when a retry occurred and excludes the final attempt. retries must equal the number of history entries.

const flakyTest = new TestBuilder()
	.name("eventually succeeds")
	.attemptId("attempt-3")
	.status("passed") // Final attempt
	.duration(120)
	.addAttemptHistoryEntry({
		attempt: 1,
		attemptId: "attempt-1",
		status: "failed",
		duration: 80,
	})
	.addAttemptHistoryEntry({
		attempt: 2,
		attemptId: "attempt-2",
		status: "failed",
		duration: 90,
	})
	.flaky()
	.build();

// flakyTest.retries === 2
// flakyTest.retryAttempts contains attempts 1 and 2; the final attempt is 3.

addRetryAttempt() remains available as a deprecated alias for addAttemptHistoryEntry().

Parsing Reports

import { parse, stringify } from "ctrf";

// Parse from string
const parsed = parse(jsonString);

// Stringify with formatting
const json = stringify(report, { pretty: true, indent: 2 });

Filtering & Querying

import { filterTests, findTest } from "ctrf";

// Filter by criteria
const filtered = filterTests(report, {
	status: "failed",
	suite: "Authentication",
	tags: ["smoke"],
});

// Find specific test
const test = findTest(report, { name: "login test" });
const testById = findTest(report, { id: "test-uuid" });

Merging Reports

import { merge } from "ctrf";

// Merge multiple reports into one
const merged = merge([report1, report2, report3], {
	deduplicateTests: true, // Remove duplicate tests by ID
});

ID Generation

import { generateTestId, generateReportId } from "ctrf";

// Generate deterministic test ID from properties
const testId = generateTestId({
	name: "should add numbers",
	suite: ["Math", "Addition"],
	filePath: "tests/math.test.ts",
});

// Generate random report ID
const reportId = generateReportId();

Insights & Analytics

import { addInsights, isTestFlaky } from "ctrf";

// Enrich a report with insights from historical data
const enriched = addInsights(currentReport, historicalReports, {
	baseline: baselineReport,
});

// Access insights
console.log(enriched.insights?.passRate); // { current: 0.95, baseline: 0.90, change: 0.05 }
console.log(enriched.insights?.flakyRate); // { current: 0.02, baseline: 0.05, change: -0.03 }

// Check if a test is flaky
const isFlaky = isTestFlaky(test);

Summary Calculation

import { calculateSummary } from "ctrf";

// Calculate summary from tests
const summary = calculateSummary(tests);
// { tests: 10, passed: 8, failed: 1, skipped: 1, pending: 0, other: 0, ... }

Constants

import {
	REPORT_FORMAT,
	CURRENT_SPEC_VERSION,
	SUPPORTED_SPEC_VERSIONS,
	TEST_STATUSES,
	CTRF_NAMESPACE,
} from "ctrf";

REPORT_FORMAT; // 'CTRF'
CURRENT_SPEC_VERSION; // '0.2.0'
SUPPORTED_SPEC_VERSIONS; // ['0.0.1', '0.0.2', '0.0.3', '0.0.4', '0.1.0', '0.2.0']
TEST_STATUSES; // ['passed', 'failed', 'skipped', 'pending', 'other']
CTRF_NAMESPACE; // UUID namespace for deterministic IDs

Error Handling

import { validateStrict, ValidationError, ParseError } from "ctrf";

try {
	validateStrict(report);
} catch (error) {
	if (error instanceof ValidationError) {
		console.error("CTRF validation failed:", error.errors);
	}
}

try {
	const parsed = parse(jsonString);
} catch (error) {
	if (error instanceof ParseError) {
		console.error("Invalid JSON:", error.message);
	}
}

Schema Access

import {
	schema,
	getSchema,
	getCurrentSpecVersion,
	getSupportedSpecVersions,
} from "ctrf";

// Get the current JSON Schema
console.log(schema);

// Get schemas for a specific version or the latest published specification
const v0_0_2Schema = getSchema("0.0.2");
const latestSchema = getSchema("latest");

// Get version info
const version = getCurrentSpecVersion(); // '0.2.0'
const supported = getSupportedSpecVersions(); // ['0.0.1', '0.0.2', '0.0.3', '0.0.4', '0.1.0', '0.2.0']

About

CTRF reference implementation in TypeScript

Resources

Code of conduct

Contributing

Security policy

Stars

5 stars

Watchers

1 watching

Forks

Releases

Used by

Contributors

Languages