or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration.mdcore-api.mdcore-classes.mdfactories.mdindex.mdplugins.mdreporters.mdtest-management.md
tile.json

reporters.mddocs/

0

# Reporter System

1

2

Built-in reporters and reporter creation for test output formatting and result reporting.

3

4

## Capabilities

5

6

### Spec Reporter

7

8

Creates a detailed, human-readable spec-style test output with hierarchical display of suites, groups, and tests.

9

10

```typescript { .api }

11

/**

12

* Create an instance of the spec reporter

13

* @param options - Optional reporter configuration

14

* @returns Named reporter contract

15

*/

16

function spec(options?: BaseReporterOptions): NamedReporterContract;

17

18

interface BaseReporterOptions {

19

/** Maximum number of stack trace frames to display */

20

framesMaxLimit?: number;

21

}

22

23

interface NamedReporterContract {

24

name: string;

25

handler: (...args: any[]) => ReporterContract;

26

}

27

```

28

29

**Usage Examples:**

30

31

```typescript

32

import { configure } from "@japa/runner";

33

import { spec } from "@japa/runner/reporters";

34

35

configure({

36

files: ["tests/**/*.spec.ts"],

37

reporters: {

38

activated: ["spec"],

39

list: [spec()],

40

},

41

});

42

43

// With custom options

44

configure({

45

files: ["tests/**/*.spec.ts"],

46

reporters: {

47

activated: ["detailed-spec"],

48

list: [

49

{

50

...spec({ framesMaxLimit: 20 }),

51

name: "detailed-spec",

52

},

53

],

54

},

55

});

56

```

57

58

### Dot Reporter

59

60

Creates a minimalist dot-style output where each test is represented by a single character (. for pass, x for fail).

61

62

```typescript { .api }

63

/**

64

* Create an instance of the dot reporter

65

* @param options - Optional reporter configuration

66

* @returns Named reporter contract

67

*/

68

function dot(options?: BaseReporterOptions): NamedReporterContract;

69

```

70

71

**Usage Examples:**

72

73

```typescript

74

import { configure } from "@japa/runner";

75

import { dot } from "@japa/runner/reporters";

76

77

configure({

78

files: ["tests/**/*.spec.ts"],

79

reporters: {

80

activated: ["dot"],

81

list: [dot()],

82

},

83

});

84

85

// Multiple reporters

86

configure({

87

files: ["tests/**/*.spec.ts"],

88

reporters: {

89

activated: ["dot", "spec"],

90

list: [dot(), spec()],

91

},

92

});

93

```

94

95

### NDJSON Reporter

96

97

Creates newline-delimited JSON output for programmatic consumption and integration with external tools.

98

99

```typescript { .api }

100

/**

101

* Create an instance of the ndjson reporter

102

* @param options - Optional reporter configuration

103

* @returns Named reporter contract

104

*/

105

function ndjson(options?: BaseReporterOptions): NamedReporterContract;

106

```

107

108

**Usage Examples:**

109

110

```typescript

111

import { configure } from "@japa/runner";

112

import { ndjson } from "@japa/runner/reporters";

113

114

configure({

115

files: ["tests/**/*.spec.ts"],

116

reporters: {

117

activated: ["ndjson"],

118

list: [ndjson()],

119

},

120

});

121

122

// Useful for CI/CD pipelines

123

configure({

124

files: ["tests/**/*.spec.ts"],

125

reporters: {

126

activated: ["ndjson", "spec"],

127

list: [

128

ndjson({ framesMaxLimit: 5 }),

129

spec(),

130

],

131

},

132

});

133

```

134

135

### GitHub Reporter

136

137

Creates GitHub Actions-compatible output with annotations and formatted messages for CI/CD integration.

138

139

```typescript { .api }

140

/**

141

* Create an instance of the github reporter

142

* @param options - Optional reporter configuration

143

* @returns Named reporter contract

144

*/

145

function github(options?: BaseReporterOptions): NamedReporterContract;

146

```

147

148

**Usage Examples:**

149

150

```typescript

151

import { configure } from "@japa/runner";

152

import { github } from "@japa/runner/reporters";

153

154

// GitHub Actions CI configuration

155

configure({

156

files: ["tests/**/*.spec.ts"],

157

reporters: {

158

activated: ["github"],

159

list: [github()],

160

},

161

});

162

163

// Combination for local development and CI

164

const isCI = process.env.CI === "true";

165

configure({

166

files: ["tests/**/*.spec.ts"],

167

reporters: {

168

activated: isCI ? ["github"] : ["spec"],

169

list: [

170

github(),

171

spec(),

172

],

173

},

174

});

175

```

176

177

### Custom Reporter Creation

178

179

Create custom reporters for specialized output formats or integrations.

180

181

```typescript { .api }

182

interface ReporterContract {

183

name: string;

184

handler: (runner: Runner, emitter: Emitter) => void;

185

}

186

187

interface Runner {

188

getSummary(): RunnerSummary;

189

onSuite(callback: (suite: Suite) => void): void;

190

}

191

192

interface Emitter {

193

on(event: string, callback: (...args: any[]) => void): void;

194

emit(event: string, ...args: any[]): void;

195

}

196

```

197

198

**Usage Examples:**

199

200

```typescript

201

import { configure } from "@japa/runner";

202

203

// Custom JSON file reporter

204

const jsonFileReporter = {

205

name: "json-file",

206

handler: (runner, emitter) => {

207

const results: any[] = [];

208

209

emitter.on("test:end", (payload) => {

210

results.push({

211

title: payload.title,

212

duration: payload.duration,

213

hasError: payload.hasError,

214

errors: payload.errors,

215

});

216

});

217

218

emitter.on("runner:end", () => {

219

const fs = require("fs");

220

fs.writeFileSync("test-results.json", JSON.stringify(results, null, 2));

221

});

222

},

223

};

224

225

// Custom Slack reporter

226

const slackReporter = {

227

name: "slack",

228

handler: (runner, emitter) => {

229

emitter.on("runner:end", async () => {

230

const summary = runner.getSummary();

231

if (summary.hasError) {

232

await sendSlackNotification(`Tests failed: ${summary.failedCount} failures`);

233

}

234

});

235

},

236

};

237

238

configure({

239

files: ["tests/**/*.spec.ts"],

240

reporters: {

241

activated: ["spec", "json-file", "slack"],

242

list: [

243

spec(),

244

jsonFileReporter,

245

slackReporter,

246

],

247

},

248

});

249

```

250

251

### Multiple Reporter Configuration

252

253

Configure multiple reporters to run simultaneously for different output needs.

254

255

**Usage Examples:**

256

257

```typescript

258

import { configure } from "@japa/runner";

259

import { spec, dot, ndjson, github } from "@japa/runner/reporters";

260

261

// Development environment

262

configure({

263

files: ["tests/**/*.spec.ts"],

264

reporters: {

265

activated: ["spec"],

266

list: [spec({ framesMaxLimit: 10 })],

267

},

268

});

269

270

// CI environment

271

configure({

272

files: ["tests/**/*.spec.ts"],

273

reporters: {

274

activated: ["github", "ndjson"],

275

list: [

276

github(),

277

ndjson(),

278

],

279

},

280

});

281

282

// Complete setup with environment detection

283

const isDevelopment = process.env.NODE_ENV === "development";

284

const isCI = process.env.CI === "true";

285

286

let activeReporters: string[];

287

if (isDevelopment) {

288

activeReporters = ["spec"];

289

} else if (isCI) {

290

activeReporters = ["github", "ndjson"];

291

} else {

292

activeReporters = ["dot"];

293

}

294

295

configure({

296

files: ["tests/**/*.spec.ts"],

297

reporters: {

298

activated: activeReporters,

299

list: [

300

spec({ framesMaxLimit: 15 }),

301

dot(),

302

ndjson({ framesMaxLimit: 5 }),

303

github(),

304

],

305

},

306

});

307

```

308

309

## Types

310

311

### Reporter Contract Types

312

313

```typescript { .api }

314

interface NamedReporterContract {

315

name: string;

316

handler: (...args: any[]) => ReporterContract;

317

}

318

319

interface ReporterContract {

320

name: string;

321

handler: (runner: Runner, emitter: Emitter) => void;

322

}

323

324

interface BaseReporterOptions {

325

framesMaxLimit?: number;

326

}

327

```

328

329

### Runner Summary Type

330

331

```typescript { .api }

332

interface RunnerSummary {

333

hasError: boolean;

334

aggregates: {

335

passed: number;

336

failed: number;

337

skipped: number;

338

todo: number;

339

total: number;

340

};

341

failureTree: Array<{

342

name: string;

343

errors: Array<{

344

phase: string;

345

error: Error;

346

}>;

347

children: Array<{

348

name: string;

349

errors: Array<{

350

phase: string;

351

error: Error;

352

}>;

353

}>;

354

}>;

355

}

356

```

357

358

### Event Types

359

360

Common events emitted by the test runner that reporters can listen to:

361

362

```typescript { .api }

363

// Runner events

364

"runner:start" | "runner:end"

365

366

// Suite events

367

"suite:start" | "suite:end"

368

369

// Group events

370

"group:start" | "group:end"

371

372

// Test events

373

"test:start" | "test:end"

374

```