Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:DevExpress Testcafe LiveModeRunner

From Leeroopedia
Knowledge Sources
Domains Testing, Live Mode, File Watching
Principle Live mode test execution
Last Updated 2026-02-12 12:00 GMT

Overview

LiveModeRunner and LiveModeController together implement TestCafe's live mode, which watches test files for changes and automatically re-runs tests without restarting the browser or the test process.

Description

Live mode is split across two primary files:

LiveModeRunner (src/live/test-runner.js, 216 lines)

LiveModeRunner extends the standard Runner class and adds live-mode-specific lifecycle management. Key behaviors:

  • Initialization: The constructor creates a LiveModeTestRunController (which manages individual test run lifecycles) and a LiveModeController (which handles file watching and keyboard input). It sets embeddingOptions with a custom TestRunCtor from the test run controller.
  • run(options): The entry point for live mode. It sets up configuration, parses the file list, initializes the controller (which starts file watching and keyboard listening), creates the runnable configuration, and runs the first test cycle. It returns a promise that resolves only when the user explicitly exits (via _waitUntilExit, a promise controlled by stopInfiniteWaiting/rejectInfiniteWaiting).
  • runTests(isFirstRun): Executes a test cycle. On subsequent runs (not the first), it re-fetches tests from the bootstrapper to pick up file changes. It finishes any previous test runs, validates configuration, sets the expected test count, resets state, restores message bus listeners, and runs the task.
  • suspend(): Stops the current test run gracefully by cancelling the runner task and waiting for in-progress tests to complete.
  • _createRunnableConfiguration(): Overrides the parent to cache the configuration, avoiding re-bootstrapping on every re-run.
  • Resource management: _disposeAssets is overridden to defer actual disposal -- assets (browser set, reporters, tested app) are stored and only disposed during final _dispose when the runner exits.

LiveModeController (src/live/controller.ts, 151 lines)

LiveModeController extends EventEmitter and orchestrates the user-facing live mode experience:

  • init(files): Registers a keyboard observer for interactive commands, starts file watching on all test files, and displays the intro message.
  • runTests(sourceChanged?): Triggers a test re-run via the runner, unless watching is paused or tests are already running.
  • onTestRunDone(err): Called after each test cycle completes. Logs results and handles the special case of test-files-not-found errors.
  • toggleWatching(): Pauses or resumes file watching (toggled by keyboard shortcut).
  • stop(): Suspends the current run via the runner.
  • restart(): Stops (if running) and re-runs tests.
  • exit(): Terminates the live mode session.
  • addFileToWatches(filename): Adds a file to the watcher dynamically.
  • dispose(): Stops file watching and removes the keyboard observer.

Usage

Live mode is activated by running TestCafe with the --live (or -L) CLI flag, or by calling the programmatic API with the live option. The runner stays active indefinitely, re-running tests when source files change or when the user presses a keyboard shortcut. It is the primary development-time workflow for TestCafe users.

Code Reference

Source Location

Signature

LiveModeRunner:

class LiveModeRunner extends Runner {
    constructor ({ proxy, browserConnectionGateway, configuration }) { ... }

    runTests (isFirstRun = false) { ... }
    run (options) { ... }
    suspend () { ... }
    stop () { ... }
    exit () { ... }

    setBootstrappingError (err) { ... }

    _validateRunOptions () { ... }
    _createRunnableConfiguration () { ... }
    _finishPreviousTestRuns () { ... }
    _validateRunnableConfiguration (isFirstRun) { ... }
    _createTask (tests, browserConnectionGroups, proxy, opts) { ... }
    _createBootstrapper (browserConnectionGateway, messageBus) { ... }
    _createController () { ... }
    _waitUntilExit () { ... }
    _disposeAssets (browserSet, reporters, testedApp) { ... }
    _dispose () { ... }
}

LiveModeController:

class LiveModeController extends EventEmitter {
    private running: boolean;
    private restarting: boolean;
    private watchingPaused: boolean;
    private stopping: boolean;
    private logger: Logger;
    private readonly runner: LiveModeRunner;
    private keyboardObserver: LiveModeKeyboardEventObserver;
    private fileWatcher: FileWatcher;

    public constructor (runner: LiveModeRunner);

    public init (files: string[]): Promise<void>;
    public dispose (): void;
    public runTests (sourceChanged?: boolean): Promise<void>;
    public onTestRunDone (err: Error): void;
    public toggleWatching (): void;
    public stop (): Promise<void>;
    public restart (): Promise<void>;
    public exit (): Promise<void>;
    public addFileToWatches (filename: string): void;

    protected _createFileWatcher (): FileWatcher;
    protected _createKeyboardObserver (): LiveModeKeyboardEventObserver;

    private _isTestFilesNotFoundError (err: Error): boolean;
    private _initFileWatching (files: string[]): void;
    private _setRunning (): void;
}

Import

import LiveModeRunner from './test-runner';
import LiveModeController from './controller';
// Internal imports only; live mode is activated via CLI flag or API option

I/O Contract

Inputs (LiveModeRunner)

Name Type Required Description
proxy Proxy Yes The testcafe-hammerhead proxy instance.
browserConnectionGateway BrowserConnectionGateway Yes Gateway managing browser connections.
configuration Configuration Yes The TestCafe configuration object.
options (to run) Object No Run-time options (same as standard runner options).

Inputs (LiveModeController)

Name Type Required Description
runner LiveModeRunner Yes The live mode runner instance this controller manages.
files (to init) string[] Yes Array of test file paths to watch for changes.

Outputs

Name Type Description
run() Promise<void> Resolves when the user exits live mode (via Ctrl+C or the exit command).
runTests() Promise<void> Resolves when a single test cycle completes.
suspend() Promise<void> Resolves when the current test run is gracefully stopped.
configurationCache null Cached runnable configuration (tests, browser connections, etc.) to avoid re-bootstrapping.

Usage Examples

# Activate live mode from the CLI
testcafe chrome tests/ --live

# Or using the short flag
testcafe chrome tests/ -L
// Programmatic API usage
const createTestCafe = require('testcafe');

async function runLiveMode () {
    const testcafe = await createTestCafe('localhost', 1337, 1338);

    const liveRunner = testcafe.createLiveModeRunner();

    await liveRunner
        .src('tests/')
        .browsers('chrome')
        .run();

    // The promise above resolves only when the user exits live mode
    await testcafe.close();
}

runLiveMode();

Keyboard shortcuts during live mode:

Key Action
Ctrl+S Toggle file watching on/off
Ctrl+R Restart current test run
Ctrl+C Stop current run / Exit live mode

Related Pages

Note: This is an orphan Implementation — live mode test execution is an internal subsystem with no dedicated Principle page.

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment