or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

assertions.mdbrowser-automation.mdclient-functions.mdelement-selection.mdindex.mdprogrammatic-api.mdrequest-interception.mduser-roles.md

programmatic-api.mddocs/

0

# Programmatic API

1

2

TestCafe's programmatic API enables you to create, configure, and run tests through JavaScript code rather than the command line, providing fine-grained control over test execution and integration with other tools.

3

4

## Capabilities

5

6

### TestCafe Instance Creation

7

8

Create and configure TestCafe instances programmatically.

9

10

```javascript { .api }

11

/**

12

* Creates a TestCafe instance for programmatic test execution

13

* @param hostname - Hostname for TestCafe servers (default: 'localhost')

14

* @param port1 - Port for main TestCafe server (default: auto-assigned)

15

* @param port2 - Port for file server (default: auto-assigned)

16

* @param sslOptions - SSL configuration for HTTPS

17

* @param developmentMode - Enable development mode features

18

* @param retryTestPages - Retry test pages on failure

19

* @param cache - Enable caching

20

* @param configFile - Path to configuration file

21

* @returns Promise resolving to TestCafe instance

22

*/

23

function createTestCafe(

24

hostname?: string,

25

port1?: number,

26

port2?: number,

27

sslOptions?: SSLOptions,

28

developmentMode?: boolean,

29

retryTestPages?: boolean,

30

cache?: boolean,

31

configFile?: string

32

): Promise<TestCafe>;

33

34

// Alternative: Configuration object approach

35

function createTestCafe(config?: TestCafeConfiguration): Promise<TestCafe>;

36

37

interface TestCafe {

38

/** Create a test runner instance */

39

createRunner(): Runner;

40

41

/** Create browser connection for remote browsers */

42

createBrowserConnection(): Promise<BrowserConnection>;

43

44

/** Create live mode runner */

45

createLiveModeRunner(): LiveModeRunner;

46

47

/** Close TestCafe instance and cleanup resources */

48

close(): Promise<void>;

49

}

50

51

interface SSLOptions {

52

key?: string;

53

cert?: string;

54

pfx?: string;

55

passphrase?: string;

56

}

57

58

interface TestCafeConfiguration {

59

hostname?: string;

60

port1?: number;

61

port2?: number;

62

ssl?: SSLOptions;

63

developmentMode?: boolean;

64

retryTestPages?: boolean;

65

cache?: boolean;

66

configFile?: string;

67

}

68

```

69

70

**Usage Examples:**

71

72

```javascript

73

import createTestCafe from 'testcafe';

74

75

// Basic TestCafe instance

76

async function runBasicTests() {

77

const testcafe = await createTestCafe('localhost', 1337, 1338);

78

79

try {

80

const runner = testcafe.createRunner();

81

82

const failedCount = await runner

83

.src(['tests/fixture1.js', 'tests/fixture2.js'])

84

.browsers(['chrome', 'firefox'])

85

.run();

86

87

console.log(`Tests failed: ${failedCount}`);

88

} finally {

89

await testcafe.close();

90

}

91

}

92

93

// Configuration object approach

94

async function runConfiguredTests() {

95

const testcafe = await createTestCafe({

96

hostname: 'localhost',

97

port1: 1337,

98

port2: 1338,

99

ssl: {

100

key: './ssl/private-key.pem',

101

cert: './ssl/certificate.pem'

102

},

103

developmentMode: true

104

});

105

106

try {

107

// Test execution code

108

} finally {

109

await testcafe.close();

110

}

111

}

112

113

// Auto-port assignment

114

async function runAutoPortTests() {

115

const testcafe = await createTestCafe(); // Uses default localhost and auto-assigned ports

116

117

try {

118

const runner = testcafe.createRunner();

119

await runner.src('tests/**/*.js').browsers('chrome').run();

120

} finally {

121

await testcafe.close();

122

}

123

}

124

```

125

126

### Test Runner Configuration

127

128

Configure test execution through the Runner interface.

129

130

```javascript { .api }

131

interface Runner {

132

/** Set test source files or globs */

133

src(source: string | string[]): Runner;

134

135

/** Set target browsers */

136

browsers(browsers: string | string[]): Runner;

137

138

/** Set test execution concurrency */

139

concurrency(concurrency: number): Runner;

140

141

/** Set test reporter */

142

reporter(reporter: string | ReporterPlugin, output?: string): Runner;

143

144

/** Set test filter */

145

filter(filter: (testName: string, fixtureName: string, fixturePath: string, testMeta: object, fixtureMeta: object) => boolean): Runner;

146

147

/** Run tests and return number of failed tests */

148

run(options?: RunOptions): Promise<number>;

149

150

/** Stop test execution */

151

stop(): Promise<void>;

152

}

153

154

interface RunOptions {

155

/** Skip JS errors in tests */

156

skipJsErrors?: boolean;

157

158

/** Disable page reloads */

159

disablePageReloads?: boolean;

160

161

/** Quarantine mode for unstable tests */

162

quarantineMode?: boolean | QuarantineOptions;

163

164

/** Debug mode */

165

debugMode?: boolean;

166

167

/** Debug on fail */

168

debugOnFail?: boolean;

169

170

/** Skip uncaught errors */

171

skipUncaughtErrors?: boolean;

172

173

/** Selector timeout */

174

selectorTimeout?: number;

175

176

/** Assertion timeout */

177

assertionTimeout?: number;

178

179

/** Page load timeout */

180

pageLoadTimeout?: number;

181

182

/** Test execution speed */

183

speed?: number;

184

185

/** Stop on first test failure */

186

stopOnFirstFail?: boolean;

187

}

188

189

interface QuarantineOptions {

190

/** Number of attempts to run failing tests */

191

attemptLimit?: number;

192

193

/** Number of successful runs required to pass */

194

successThreshold?: number;

195

}

196

```

197

198

**Usage Examples:**

199

200

```javascript

201

async function configureRunner() {

202

const testcafe = await createTestCafe();

203

204

try {

205

const runner = testcafe.createRunner();

206

207

const failedCount = await runner

208

.src(['tests/login.js', 'tests/checkout.js'])

209

.browsers(['chrome:headless', 'firefox:headless'])

210

.concurrency(3)

211

.reporter('spec')

212

.filter((testName, fixtureName) => {

213

return testName.includes('critical') || fixtureName.includes('smoke');

214

})

215

.run({

216

skipJsErrors: true,

217

quarantineMode: true,

218

speed: 0.8,

219

stopOnFirstFail: false,

220

selectorTimeout: 10000,

221

assertionTimeout: 5000

222

});

223

224

if (failedCount > 0) {

225

console.error(`${failedCount} tests failed`);

226

process.exit(1);

227

}

228

} finally {

229

await testcafe.close();

230

}

231

}

232

233

// Multiple reporter configuration

234

async function runWithMultipleReporters() {

235

const testcafe = await createTestCafe();

236

237

try {

238

const runner = testcafe.createRunner();

239

240

await runner

241

.src('tests/**/*.js')

242

.browsers('chrome')

243

.reporter([

244

{

245

name: 'spec',

246

output: process.stdout

247

},

248

{

249

name: 'json',

250

output: 'reports/test-results.json'

251

},

252

{

253

name: 'xunit',

254

output: 'reports/test-results.xml'

255

}

256

])

257

.run();

258

} finally {

259

await testcafe.close();

260

}

261

}

262

```

263

264

### Browser Management

265

266

Manage browser connections and configurations.

267

268

```javascript { .api }

269

interface BrowserConnection {

270

/** Browser connection URL for remote browsers */

271

url: string;

272

273

/** Unique identifier for the connection */

274

id: string;

275

276

/** Connection ready promise */

277

ready: Promise<void>;

278

279

/** Establish browser connection */

280

establish(userAgent: string): Promise<void>;

281

282

/** Close browser connection */

283

close(): Promise<void>;

284

}

285

286

interface LiveModeRunner extends Runner {

287

/** Watch files for changes */

288

watchFiles(files: string | string[]): LiveModeRunner;

289

290

/** Start live mode */

291

run(): Promise<void>;

292

293

/** Stop live mode */

294

stop(): Promise<void>;

295

}

296

```

297

298

**Usage Examples:**

299

300

```javascript

301

// Remote browser connection

302

async function setupRemoteBrowser() {

303

const testcafe = await createTestCafe();

304

305

try {

306

const connection = await testcafe.createBrowserConnection();

307

308

console.log(`Connect remote browser to: ${connection.url}`);

309

310

// Wait for browser to connect

311

await connection.ready;

312

console.log('Remote browser connected');

313

314

const runner = testcafe.createRunner();

315

316

await runner

317

.src('tests/remote-tests.js')

318

.browsers(connection)

319

.run();

320

321

} finally {

322

await testcafe.close();

323

}

324

}

325

326

// Live mode testing

327

async function runLiveMode() {

328

const testcafe = await createTestCafe();

329

330

try {

331

const liveRunner = testcafe.createLiveModeRunner();

332

333

await liveRunner

334

.src('tests/live-tests.js')

335

.browsers('chrome')

336

.watchFiles(['tests/**/*.js', 'src/**/*.js'])

337

.run();

338

339

} finally {

340

await testcafe.close();

341

}

342

}

343

344

// Multiple browser connections

345

async function runMultipleBrowsers() {

346

const testcafe = await createTestCafe();

347

348

try {

349

const connection1 = await testcafe.createBrowserConnection();

350

const connection2 = await testcafe.createBrowserConnection();

351

352

console.log(`Browser 1: ${connection1.url}`);

353

console.log(`Browser 2: ${connection2.url}`);

354

355

await Promise.all([connection1.ready, connection2.ready]);

356

357

const runner = testcafe.createRunner();

358

359

await runner

360

.src('tests/cross-browser.js')

361

.browsers([connection1, connection2, 'chrome:headless'])

362

.concurrency(3)

363

.run();

364

365

} finally {

366

await testcafe.close();

367

}

368

}

369

```

370

371

### Advanced Configuration

372

373

Advanced TestCafe configuration and customization options.

374

375

```javascript { .api }

376

// Custom reporter integration

377

interface ReporterPlugin {

378

reportTaskStart(startTime: Date, userAgents: string[], testCount: number): void;

379

reportFixtureStart(name: string, path: string, meta: object): void;

380

reportTestStart(name: string, meta: object): void;

381

reportTestDone(name: string, testRunInfo: TestRunInfo): void;

382

reportTaskDone(endTime: Date, passed: number, warnings: string[], result: object): void;

383

}

384

385

interface TestRunInfo {

386

errs: TestError[];

387

durationMs: number;

388

unstable: boolean;

389

screenshotPath: string;

390

screenshots: Screenshot[];

391

videos: Video[];

392

quarantine: object;

393

skipped: boolean;

394

}

395

396

// Custom browser provider

397

interface BrowserProvider {

398

openBrowser(id: string, pageUrl: string, browserName: string): Promise<void>;

399

closeBrowser(id: string): Promise<void>;

400

resizeWindow(id: string, width: number, height: number): Promise<void>;

401

takeScreenshot(id: string, screenshotPath: string, pageWidth: number, pageHeight: number): Promise<void>;

402

}

403

```

404

405

**Usage Examples:**

406

407

```javascript

408

// Custom reporter

409

class CustomReporter {

410

reportTaskStart(startTime, userAgents, testCount) {

411

console.log(`Starting ${testCount} tests at ${startTime}`);

412

console.log(`User agents: ${userAgents.join(', ')}`);

413

}

414

415

reportFixtureStart(name, path, meta) {

416

console.log(`\n=== Fixture: ${name} ===`);

417

console.log(`Path: ${path}`);

418

}

419

420

reportTestStart(name, meta) {

421

console.log(`\n► Running: ${name}`);

422

}

423

424

reportTestDone(name, testRunInfo) {

425

const status = testRunInfo.errs.length > 0 ? 'FAILED' : 'PASSED';

426

const duration = testRunInfo.durationMs;

427

428

console.log(`◄ ${status}: ${name} (${duration}ms)`);

429

430

if (testRunInfo.errs.length > 0) {

431

testRunInfo.errs.forEach(err => {

432

console.error(` Error: ${err.errMsg}`);

433

});

434

}

435

436

if (testRunInfo.screenshots.length > 0) {

437

console.log(` Screenshots: ${testRunInfo.screenshots.length}`);

438

}

439

}

440

441

reportTaskDone(endTime, passed, warnings, result) {

442

console.log(`\n=== Test Results ===`);

443

console.log(`Passed: ${passed}`);

444

console.log(`Failed: ${result.failedCount}`);

445

console.log(`Total: ${result.passedCount + result.failedCount}`);

446

console.log(`Duration: ${endTime - result.startTime}ms`);

447

448

if (warnings.length > 0) {

449

console.log(`Warnings: ${warnings.length}`);

450

}

451

}

452

}

453

454

async function runWithCustomReporter() {

455

const testcafe = await createTestCafe();

456

457

try {

458

const runner = testcafe.createRunner();

459

460

await runner

461

.src('tests/**/*.js')

462

.browsers('chrome')

463

.reporter(new CustomReporter())

464

.run();

465

466

} finally {

467

await testcafe.close();

468

}

469

}

470

471

// Configuration with environment variables

472

async function runEnvironmentSpecificTests() {

473

const config = {

474

hostname: process.env.TESTCAFE_HOSTNAME || 'localhost',

475

port1: parseInt(process.env.TESTCAFE_PORT1) || undefined,

476

port2: parseInt(process.env.TESTCAFE_PORT2) || undefined,

477

developmentMode: process.env.NODE_ENV === 'development'

478

};

479

480

const testcafe = await createTestCafe(config);

481

482

try {

483

const runner = testcafe.createRunner();

484

485

const browsers = process.env.BROWSERS

486

? process.env.BROWSERS.split(',')

487

: ['chrome:headless'];

488

489

const sources = process.env.TEST_FILES

490

? process.env.TEST_FILES.split(',')

491

: ['tests/**/*.js'];

492

493

await runner

494

.src(sources)

495

.browsers(browsers)

496

.concurrency(parseInt(process.env.CONCURRENCY) || 1)

497

.run({

498

speed: parseFloat(process.env.TEST_SPEED) || 1,

499

skipJsErrors: process.env.SKIP_JS_ERRORS === 'true',

500

quarantineMode: process.env.QUARANTINE_MODE === 'true'

501

});

502

503

} finally {

504

await testcafe.close();

505

}

506

}

507

```

508

509

### Integration Examples

510

511

Real-world integration examples with build systems and CI/CD.

512

513

```javascript { .api }

514

// Integration with build systems

515

async function integrationWithBuildSystem() {

516

// Pre-test setup

517

console.log('Building application...');

518

await buildApplication();

519

520

console.log('Starting test server...');

521

const server = await startTestServer();

522

523

const testcafe = await createTestCafe();

524

525

try {

526

const runner = testcafe.createRunner();

527

528

const failedCount = await runner

529

.src('tests/integration/**/*.js')

530

.browsers(['chrome:headless'])

531

.run({

532

pageLoadTimeout: 30000,

533

assertionTimeout: 10000

534

});

535

536

// Post-test cleanup

537

console.log('Stopping test server...');

538

await server.close();

539

540

if (failedCount > 0) {

541

throw new Error(`${failedCount} tests failed`);

542

}

543

544

} finally {

545

await testcafe.close();

546

}

547

}

548

549

// Parallel test execution

550

async function runParallelTests() {

551

const testGroups = [

552

'tests/unit/**/*.js',

553

'tests/integration/**/*.js',

554

'tests/e2e/**/*.js'

555

];

556

557

const results = await Promise.all(

558

testGroups.map(async (group) => {

559

const testcafe = await createTestCafe();

560

561

try {

562

const runner = testcafe.createRunner();

563

564

const failedCount = await runner

565

.src(group)

566

.browsers('chrome:headless')

567

.run();

568

569

return { group, failedCount };

570

} finally {

571

await testcafe.close();

572

}

573

})

574

);

575

576

const totalFailed = results.reduce((sum, result) => sum + result.failedCount, 0);

577

578

results.forEach(result => {

579

console.log(`${result.group}: ${result.failedCount} failed`);

580

});

581

582

if (totalFailed > 0) {

583

process.exit(1);

584

}

585

}

586

587

// Conditional test execution

588

async function runConditionalTests() {

589

const testcafe = await createTestCafe();

590

591

try {

592

const runner = testcafe.createRunner();

593

594

// Filter tests based on environment or conditions

595

const testFilter = (testName, fixtureName, fixturePath, testMeta, fixtureMeta) => {

596

// Skip slow tests in CI

597

if (process.env.CI && testMeta.slow) {

598

return false;

599

}

600

601

// Run only smoke tests in staging

602

if (process.env.ENVIRONMENT === 'staging' && !testMeta.smoke) {

603

return false;

604

}

605

606

// Skip browser-specific tests

607

if (testMeta.browserSpecific && !testMeta.browserSpecific.includes(process.env.BROWSER)) {

608

return false;

609

}

610

611

return true;

612

};

613

614

await runner

615

.src('tests/**/*.js')

616

.browsers(process.env.BROWSER || 'chrome:headless')

617

.filter(testFilter)

618

.run();

619

620

} finally {

621

await testcafe.close();

622

}

623

}

624

```