Jump to content

Connect Leeroopedia MCP: Equip your AI agents to search best practices, build plans, verify code, diagnose failures, and look up hyperparameter defaults.

Implementation:DevExpress Testcafe Compiler GetTests

From Leeroopedia
Knowledge Sources
Domains Testing, Web_Automation
Last Updated 2026-02-12 04:00 GMT

Overview

Concrete test file compilation system for TestCafe that transforms source files in multiple formats into executable Test objects.

Description

The Compiler class orchestrates multi-format test file compilation through a plugin-based compiler system. The getTests() method processes all source files by chunking them into batches (1000 files per chunk to avoid filesystem limits), detecting appropriate compilers based on file extension and content, optionally precompiling batches for performance, and executing each file to extract Test objects through the TestCafe API registration mechanism.

Supported file extensions include .js, .ts, .jsx, .tsx, .coffee, .cjs, and .mjs. The compiler uses strip-bom to handle Unicode byte-order marks, lodash for array operations, and delegates to specialized compilers initialized via initTestFileCompilers(). The system supports both CommonJS and ESM modes, with conditional ESM loader usage based on Node.js version.

The createTestFileInfo() static method reads file contents, strips BOM, and matches against registered compilers. Files that don't match any compiler are skipped. Precompilation is used for TypeScript batch transpilation, while individual compilation handles runtime test registration.

Usage

Use the Compiler when initializing a test run to transform source file paths into executable Test objects that can be scheduled and executed.

Code Reference

Source Location

  • Repository: testcafe
  • File: src/compiler/index.js
  • Lines: L17-128

Signature

class Compiler {
    constructor(sources: string[], compilerOptions: object, { baseUrl?, esm? })

    async getTests(): Promise<Test[]>

    static getSupportedTestFileExtensions(): string[]
    static async createTestFileInfo(filename: string, esm?: boolean): Promise<TestFileInfo>
    static cleanUp(): void
}

Import

import Compiler from './compiler';

// Initialize compiler
const compiler = new Compiler(
    ['tests/**/*.js', 'tests/**/*.ts'],
    { typescript: { configPath: './tsconfig.json' } },
    { baseUrl: '/project/root', esm: false }
);

// Get all tests
const tests = await compiler.getTests();

I/O Contract

Inputs

Name Type Required Description
sources string[] Yes Array of file paths to compile
compilerOptions object No Compiler-specific options (TypeScript config, Babel presets, etc.)
baseUrl string No Base URL for resolving relative imports
esm boolean No Enable ES module mode (default: false)

Outputs

Name Type Description
tests Test[] Array of Test objects with fixture and metadata
Test.name string Test name from test() call
Test.fixture Fixture Parent fixture object
Test.fn Function Test implementation function
Test.meta object Metadata tags from .meta()

Usage Examples

Basic Compilation

import Compiler from './compiler/index';

// Compile JavaScript and TypeScript tests
const compiler = new Compiler(
    [
        'tests/auth.test.js',
        'tests/checkout.test.ts'
    ],
    {},
    { esm: false }
);

const tests = await compiler.getTests();
console.log(`Compiled ${tests.length} tests`);

// Clean up compiler resources
Compiler.cleanUp();

TypeScript with Custom Config

const compiler = new Compiler(
    ['tests/**/*.ts'],
    {
        typescript: {
            configPath: './tsconfig.test.json',
            customCompilerModulePath: 'typescript'
        }
    },
    { baseUrl: process.cwd() }
);

const tests = await compiler.getTests();

ESM Mode

// Compile ES modules (.mjs files)
const compiler = new Compiler(
    ['tests/**/*.mjs'],
    {},
    { esm: true }
);

const tests = await compiler.getTests();

Get Supported Extensions

const extensions = Compiler.getSupportedTestFileExtensions();
// Returns: ['.js', '.ts', '.jsx', '.tsx', '.coffee', '.cjs', '.mjs']

console.log(`Supported extensions: ${extensions.join(', ')}`);

Compilation Pipeline Implementation

// Internal compilation flow from index.js
async getTests() {
    // Split into chunks to avoid file handle limits
    const sourceChunks = chunk(this.sources, 1000);
    let tests = [];

    while (sourceChunks.length) {
        const chunkTests = await this._compileTestFiles(sourceChunks.shift());
        tests = tests.concat(chunkTests);
    }

    Compiler.cleanUp();
    return flattenDeep(tests).filter(test => !!test);
}

async _compileTestFiles(filenames) {
    // Create file info objects
    const testFilesInfo = await this._createTestFilesInfo(filenames);

    // Group by compiler
    const compilerTasks = this._getCompilerTasks(testFilesInfo);

    // Precompile batches (e.g., TypeScript)
    await Promise.all(compilerTasks.map(({ compiler, compilerTestFilesInfo }) =>
        this._precompileFiles(compiler, compilerTestFilesInfo)
    ));

    // Execute each file to extract tests
    const tests = [];
    for (const info of testFilesInfo) {
        tests.push(await this._getTests(info));
    }

    return tests;
}

File Info Creation

static async createTestFileInfo(filename, esm = false) {
    // Read file
    let code = await readFile(filename);
    code = stripBom(code).toString();

    // Find matching compiler
    const compiler = find(
        getTestFileCompilers(esm),
        someCompiler => someCompiler.canCompile(code, filename)
    );

    if (!compiler) return null;

    return {
        filename,
        code,
        compiler,
        compiledCode: null
    };
}

Related Pages

Implements Principle

Requires Environment

Page Connections

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