Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Octopodo/kt-testing-suite-core/llms.txt

Use this file to discover all available pages before exploring further.

Reporters are the output layer of KT Testing Suite Core. The runner knows nothing about how results should be presented—it simply calls well-defined lifecycle methods on whatever object you pass as the reporter. The library ships two built-in implementations: ConsoleReporter, which prints human-readable lines via $.writeln, and JSONReporter, which additionally builds a structured result tree and emits JSON either to a file or as delimited output on $.writeln. You can also implement the TestReporter interface yourself to produce any output format you need.

Type Definitions

TestResult

interface TestResult {
    name: string;
    status: 'passed' | 'failed' | 'skipped';
    error?: {
        message: string;
        fileName?: string;
        line?: number;
    };
    duration?: number;
}
Describes the outcome of a single test case as passed to onTestEnd.
name
string
required
The test name as passed to it().
status
'passed' | 'failed' | 'skipped'
required
The result of the test run. The runner currently sets 'passed' or 'failed'; 'skipped' is available for custom reporters or future use.
error
object
Present only when status is 'failed'. Contains the details of the thrown error.
duration
number
Elapsed time in milliseconds for this test. Not currently populated by the built-in runner but included in the interface for custom implementations.

SuiteResult

interface SuiteResult {
    description: string;
    tests: TestResult[];
    suites: SuiteResult[];
}
Represents the collected results for one suite, including all its direct tests and any nested child suites. JSONReporter builds a tree of these objects as the run progresses.
description
string
required
The suite label as passed to describe().
tests
TestResult[]
required
The results of all tests registered directly on this suite.
suites
SuiteResult[]
required
Results for any nested describe blocks inside this suite.

TestReporter interface

interface TestReporter {
    onStart(): void;
    onSuiteStart(suite: Suite): void;
    onTestStart(test: Test): void;
    onTestEnd(test: Test, result: TestResult): void;
    onSuiteEnd(suite: Suite): void;
    onFinished(results: { passed: number; failed: number; total: number }): void;
}
All six methods must be implemented. The runner calls them in the order described below.
onStart()
void
Called once before any suite is processed. Use this to initialise state, print a header, or open output streams.
onSuiteStart(suite: Suite)
void
Called each time the runner begins processing a suite (including nested suites). suite is the raw Suite object, not a SuiteResult.
onTestStart(test: Test)
void
Called immediately before a test function is invoked. test is the raw Test object containing name and fn.
onTestEnd(test: Test, result: TestResult)
void
Called after a test finishes, whether it passed or failed. result carries the outcome and any error details.
onSuiteEnd(suite: Suite)
void
Called after all tests and child suites in a suite have been processed (inside the finally block, so it always runs).
onFinished(results)
void
Called once after all root suites have been processed. results contains aggregate passed, failed, and total counts.

ConsoleReporter

class ConsoleReporter implements TestReporter
The default reporter. Prints human-readable output to the ExtendScript console using $.writeln. All six TestReporter methods are implemented; onStart and onSuiteEnd are no-ops.

Output Format

Suite: <suite.description>
  Test: <test.name>
    ✅ Passed
  Test: <failing test name>
    ❌ Failed: <error.message>
                            <error.fileName>
                            <error.line>

Test Results:
Passed: <n>
Failed: <n>

Method Implementations

MethodBehaviour
onStart()No-op
onSuiteStart(suite)$.writeln('Suite: ' + suite.description)
onTestStart(test)$.writeln(' Test: ' + test.name)
onTestEnd(test, result)Prints ✅ Passed, ❌ Failed: …, or ⚠️ Skipped
onSuiteEnd(suite)No-op
onFinished(results)Prints the summary block with passed/failed counts

Example

import { runTests, ConsoleReporter } from 'kt-testing-suite-core';

// ConsoleReporter is the default; these are equivalent:
runTests();
runTests(undefined, new ConsoleReporter());

JSONReporter

class JSONReporter implements TestReporter {
    constructor(outputPath?: string)
}
Composes a ConsoleReporter internally and delegates all console-output calls to it, while additionally building a structured SuiteResult tree during the run and emitting a JSON document when onFinished is called.

constructor()

outputPath
string
An absolute file path where the JSON report should be written. If omitted, the JSON is written to $.writeln wrapped in delimiter lines (see JSON Output Format below). If provided, the runner will attempt to open the file for writing via the ExtendScript File API.

Internal State

JSONReporter maintains two private data structures alongside a ConsoleReporter delegate:
rootSuites
SuiteResult[]
The list of top-level SuiteResult objects. Populated during onSuiteStart / onSuiteEnd as the runner traverses the tree.
suiteStack
SuiteResult[]
A stack that tracks the currently active suite during traversal. onSuiteStart pushes a new SuiteResult; onSuiteEnd pops it. Nested suites are automatically linked to their parent via parent.suites.push(child).

Delegation to ConsoleReporter

JSONReporter delegates every console-output operation to an internal ConsoleReporter instance. This means running with JSONReporter produces the same human-readable output as ConsoleReporter plus the JSON document at the end.
JSONReporter methodConsole delegation
onStart()Resets rootSuites and suiteStack, then calls consoleReporter.onStart()
onSuiteStart(suite)Builds SuiteResult, links to parent or rootSuites, calls consoleReporter.onSuiteStart()
onTestStart(test)Calls consoleReporter.onTestStart()
onTestEnd(test, result)Pushes result onto current suite’s tests, calls consoleReporter.onTestEnd()
onSuiteEnd(suite)Pops suiteStack, calls consoleReporter.onSuiteEnd()
onFinished(results)Calls consoleReporter.onFinished(), then emits JSON

JSON Output Format

The emitted JSON has the following shape:
{
    stats: {
        passed: number;
        failed: number;
        total: number;
    };
    suites: SuiteResult[];
}
When outputPath is not set, the JSON is written to $.writeln between two delimiter lines that allow an external script or host process to extract it reliably:
JSON_OUTPUT_START
{
  "stats": { "passed": 3, "failed": 1, "total": 4 },
  "suites": [ ... ]
}
JSON_OUTPUT_END
When outputPath is set, the JSON is written directly to the file using the ExtendScript File API. If the write fails, an error is logged to $.writeln:
    ⚠️ Error writing JSON report to /path/to/file: <message>

Example

import { runTests, JSONReporter } from 'kt-testing-suite-core';

runTests(undefined, new JSONReporter('/tmp/test-results.json'));

Sample JSON output

{
  "stats": {
    "passed": 2,
    "failed": 1,
    "total": 3
  },
  "suites": [
    {
      "description": "Math operations",
      "tests": [
        { "name": "adds numbers", "status": "passed" },
        { "name": "subtracts numbers", "status": "passed" }
      ],
      "suites": []
    },
    {
      "description": "String operations",
      "tests": [
        {
          "name": "detects empty string",
          "status": "failed",
          "error": {
            "message": "Expected 'hello' to be empty",
            "fileName": "tests.ts",
            "line": 42
          }
        }
      ],
      "suites": []
    }
  ]
}

Implementing a Custom Reporter

Implement TestReporter to produce any output you need—XML, a CEP panel message, a BridgeTalk packet, or anything else.
import { TestReporter, TestResult } from 'kt-testing-suite-core';
import { Suite, Test } from 'kt-testing-suite-core';

class TAPReporter implements TestReporter {
    private testNumber = 0;

    onStart(): void {
        $.writeln('TAP version 13');
    }

    onSuiteStart(suite: Suite): void {
        $.writeln('# ' + suite.description);
    }

    onTestStart(test: Test): void {
        // no-op
    }

    onTestEnd(test: Test, result: TestResult): void {
        this.testNumber++;
        if (result.status === 'passed') {
            $.writeln('ok ' + this.testNumber + ' - ' + test.name);
        } else {
            $.writeln('not ok ' + this.testNumber + ' - ' + test.name);
            if (result.error) {
                $.writeln('  ---');
                $.writeln('  message: ' + result.error.message);
                $.writeln('  ...');
            }
        }
    }

    onSuiteEnd(suite: Suite): void {
        // no-op
    }

    onFinished(results: { passed: number; failed: number; total: number }): void {
        $.writeln('1..' + results.total);
    }
}

// Use it
import { runTests } from 'kt-testing-suite-core';
runTests(undefined, new TAPReporter());
If you want both human-readable console output and your custom format, instantiate a ConsoleReporter inside your class and delegate to it the same way JSONReporter does.

Build docs developers (and LLMs) love