or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-karma-coveralls

A karma plugin which uploads coverage reports to coveralls.io

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/karma-coveralls@2.1.x

To install, run

npx @tessl/cli install tessl/npm-karma-coveralls@2.1.0

index.mddocs/

karma-coveralls

karma-coveralls is a Karma plugin that automatically uploads code coverage reports generated by karma-coverage to the coveralls.io service. It acts as a bridge between the Karma test runner ecosystem and the Coveralls coverage tracking platform, enabling continuous monitoring of test coverage in JavaScript projects.

Package Information

  • Package Name: karma-coveralls
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install karma-coveralls --save-dev

Core Imports

Since this is a Karma plugin, it's registered via Karma's plugin system rather than imported directly:

// karma.conf.js
module.exports = function(config) {
  config.set({
    plugins: [
      'karma-coverage',
      'karma-coveralls'
    ],
    reporters: ['coverage', 'coveralls']
  });
};

Basic Usage

// karma.conf.js
module.exports = function(config) {
  config.set({
    // Basic reporter configuration
    reporters: ['coverage', 'coveralls'],
    
    // Coverage reporter setup (required)
    coverageReporter: {
      type: 'lcov',
      dir: 'coverage/'
    },
    
    // Optional coveralls-specific configuration
    coverallsReporter: {
      repoToken: process.env.COVERALLS_REPO_TOKEN
    }
  });
};

Environment variable configuration:

# Set repository token
export COVERALLS_REPO_TOKEN=your_repo_token_here

# Run Karma tests
npm test

Capabilities

Coveralls Reporter

The main functionality provided by karma-coveralls is the coveralls reporter that processes LCOV coverage data and uploads it to coveralls.io.

/**
 * Coveralls reporter constructor for Karma
 * Registered as 'reporter:coveralls' in Karma's plugin system
 * @param rootConfig - Karma configuration object
 * @param helper - Karma helper utilities  
 * @param logger - Karma logger instance
 */
function CoverallsReporter(rootConfig, helper, logger): void;

// Plugin registration
module.exports = {
  'reporter:coveralls': ['type', CoverallsReporter]
};

The reporter includes dependency injection configuration:

CoverallsReporter.$inject = ['config', 'helper', 'logger'];

Configuration Options

Karma Configuration

The plugin integrates with standard Karma configuration:

interface KarmaConfig {
  /** Array of reporters including 'coveralls' */
  reporters: string[];
  /** Coverage reporter configuration (required) */
  coverageReporter?: CoverageReporterConfig;
  /** Coverage Istanbul reporter configuration (alternative) */
  coverageIstanbulReporter?: CoverageIstanbulReporterConfig;
  /** Coveralls-specific configuration */
  coverallsReporter?: CoverallsReporterConfig;
  /** Base path for resolving coverage files */
  basePath?: string;
  /** Auto-watch mode (disables coveralls reporter) */
  autoWatch?: boolean;
}

Coverage Reporter Configuration

interface CoverageReporterConfig {
  /** Coverage report type - must include 'lcov', 'lcovonly', or 'html' */
  type?: 'lcov' | 'lcovonly' | 'html' | string;
  /** Directory for coverage files */
  dir?: string;
  /** Array of reporter configurations */
  reporters?: Array<{
    /** Reporter type - must include 'lcov', 'lcovonly', or 'html' for coveralls */
    type: 'lcov' | 'lcovonly' | 'html' | string;
    /** Directory path for this reporter's output */
    dir?: string;
  }>;
}

Coverage Istanbul Reporter Configuration

interface CoverageIstanbulReporterConfig {
  /** Directory for coverage files */
  dir?: string;
  /** Array of reporter types - must include 'lcov' for coveralls */
  reporters?: Array<'lcov' | 'lcovonly' | 'html' | 'text' | string>;
  /** Report directory structure */
  reports?: Array<{
    type: 'lcov' | 'lcovonly' | 'html' | 'text' | string;
    dir?: string;
  }>;
}

Coveralls Reporter Configuration

interface CoverallsReporterConfig {
  /** Repository token for Coveralls authentication */
  repoToken?: string;
}

Reporter Methods

The CoverallsReporter class provides the following methods:

/**
 * Called when Karma exits, handles coverage upload
 * @param done - Callback function to signal completion
 */
onExit(done: () => void): void;

Internal Functions

The plugin includes several internal utility functions:

/**
 * Resolves which coverage reporter configuration to use
 * @returns CoverageReporterConfig or CoverageIstanbulReporterConfig
 * @throws Error if coverage reporter doesn't precede coveralls reporter
 */
function resolve_coverage_reporter(): CoverageReporterConfig | CoverageIstanbulReporterConfig;

/**
 * Attempts to read LCOV files from the specified directory
 * @param basepath - Directory path to search for lcov.info files
 * @param retry - Callback function for retry attempts  
 * @param done - Completion callback with LCOV content
 */
function try_read_lcov(
  basepath: string, 
  retry: () => void, 
  done: (content?: string) => void
): void;

/**
 * Reads LCOV files with retry logic (up to 5 attempts)
 * @param basepath - Directory path to search for lcov.info files
 * @param finish - Completion callback with LCOV content
 */
function read_lcov(basepath: string, finish: (content?: string) => void): void;

/**
 * Handles response from Coveralls API and logs results
 * @param done - Karma completion callback
 * @param err - Error from Coveralls API
 * @param response - HTTP response object
 * @param body - Response body content
 */
function send_to_coveralls(
  done: () => void,
  err: Error | null,
  response: { statusCode: number } | undefined,
  body: string
): void;

/**
 * Formats success response from Coveralls API
 * @param body - Response body (string or parsed JSON)
 * @returns Formatted success message
 */
function success(body: string | { message?: string; url?: string }): string;

Configuration Requirements

Reporter Order

The coverage reporter must precede the coveralls reporter in the reporters array:

// Correct
reporters: ['coverage', 'coveralls']
reporters: ['coverage-istanbul', 'coveralls']

// Incorrect - will throw error
reporters: ['coveralls', 'coverage']

Coverage Format

The coverage reporter must generate LCOV format output:

coverageReporter: {
  type: 'lcov', // or 'lcovonly'
  dir: 'coverage/'
}

Authentication

Repository token can be provided via:

  1. Environment variable:
export COVERALLS_REPO_TOKEN=your_token
  1. Karma configuration:
coverallsReporter: {
  repoToken: 'your_token'
}
  1. .coveralls.yml file:
repo_token: your_token

File System Behavior

LCOV File Discovery

The plugin automatically discovers LCOV files using the following logic:

  1. Searches for lcov.info files in the coverage directory
  2. Uses the first matching coverage reporter configuration:
    • HTML, LCOV, or LCOVONLY reporter with explicit dir property
    • Falls back to coverageReporter.dir or coverageIstanbulReporter.dir
    • Defaults to ./coverage if no directory specified

File Processing

/**
 * LCOV file processing workflow:
 * 1. Discovers lcov.info files using vinyl-fs glob pattern: '**\/lcov.info'
 * 2. Merges multiple LCOV files using lcov-result-merger through stream processing
 * 3. Converts merged LCOV to Coveralls format via coveralls.convertLcovToCoveralls()
 * 4. Uploads to Coveralls API via coveralls.sendToCoveralls()
 * 
 * Stream processing chain:
 * vfs.src() -> through2.obj() -> lcovResultMerger() -> through2.obj() -> done()
 */

/**
 * LCOV file discovery logic priority order:
 * 1. First reporter in coverageReporter.reporters[] with type 'html', 'lcov', or 'lcovonly' and dir property
 * 2. coverageReporter.dir (if no specific reporter dir found)
 * 3. './coverage' (default fallback)
 */
interface LcovDiscoveryConfig {
  /** Resolved path to directory containing lcov.info files */
  filepath: string;
  /** Source configuration that provided the path */
  source: 'reporter' | 'coverage' | 'default';
}

Retry Logic

The plugin includes retry logic when LCOV files are not immediately available:

  • Retries up to 5 times with 200ms delays
  • Handles timing issues when coverage files are being written

Error Handling

Configuration Errors

/**
 * Configuration validation errors thrown by the plugin:
 */
interface ConfigurationError extends Error {
  message: "coverage or coverage-istanbul reporter should precede coveralls";
}

/**
 * Thrown when coveralls reporter appears before coverage reporter in config
 * @throws ConfigurationError
 */
function validateReporterOrder(): void;

Runtime Behavior

  • Auto-watch mode: Reporter disables itself automatically with info log "disabled due to --auto-watch"
  • Missing LCOV files: Completes without error (no upload), retries up to 5 times with 200ms delays
  • API errors: Logged but don't cause Karma to fail
  • Network issues: Handled gracefully with error logging

HTTP Response Handling

/**
 * HTTP response status codes and handling:
 * - 200-299 with valid JSON: Success, logs formatted message
 * - Other status codes: Error, logs status code and raw response body
 * - Missing response object: Creates default response with statusCode: 0
 * - Invalid JSON in response: Treated as error response
 */
interface CoverallsResponse {
  statusCode: number;
  body?: string;
}

/**
 * Success response format from Coveralls API
 */
interface CoverallsSuccessBody {
  message?: string;
  url?: string;
}

Logging Behavior

The plugin provides detailed logging through Karma's logger:

/**
 * Log levels and messages used by the plugin:
 * - log.info('disabled due to --auto-watch') - When auto-watch is enabled
 * - log.debug('use lcov.info in %s', filepath) - Coverage directory path
 * - log.info('uploading...') - Before sending to Coveralls
 * - log.info('%d --- %s', statusCode, message) - Upload result
 */
interface LoggerMethods {
  info(message: string, ...args: any[]): void;
  debug(message: string, ...args: any[]): void;
}

Dependencies

The plugin relies on the following dependencies:

/**
 * Required dependencies and their usage:
 * - coveralls: ~3.0.0 - Coveralls.io API client for authentication and upload
 * - lcov-result-merger: ^3.0.0 - Merges multiple LCOV files into single stream
 * - through2: ^2.0.0 - Stream transformation utilities for file processing
 * - vinyl-fs: ^3.0.2 - File system operations with vinyl objects for glob patterns
 * 
 * Core Node.js modules used:
 * - fs: File system operations for checking file existence
 * - path: Path manipulation for resolving coverage directories
 */

/**
 * Dependency injection pattern used by Karma
 */
interface KarmaDependencyInjection {
  /** Configuration object containing all Karma settings */
  config: KarmaConfig;
  /** Karma helper utilities for type checking and validation */
  helper: KarmaHelper;
  /** Karma logger factory for creating named loggers */
  logger: KarmaLogger;
}

interface KarmaHelper {
  /** Checks if a value is defined (not null or undefined) */
  isDefined(value: any): boolean;
}

interface KarmaLogger {
  /** Creates a named logger instance */
  create(name: string): LoggerMethods;
}

Integration Points

Karma Plugin System

The plugin registers with Karma as a reporter:

// Plugin exports
module.exports = {
  'reporter:coveralls': ['type', CoverallsReporter]
};

Coverage Reporters

Works with both karma-coverage and karma-coverage-istanbul:

  • karma-coverage: Uses coverageReporter configuration
  • karma-coverage-istanbul: Uses coverageIstanbulReporter configuration

Coveralls.io API

Integrates with the Coveralls service for:

  • Authentication via repository tokens
  • LCOV data conversion and formatting
  • Coverage report upload and processing
  • Response handling and error reporting
/**
 * Coveralls API integration workflow:
 * 1. coveralls.getBaseOptions() - Gets base configuration and authentication
 * 2. coveralls.convertLcovToCoveralls() - Converts LCOV to Coveralls format
 * 3. coveralls.sendToCoveralls() - Uploads coverage data to Coveralls API
 */

/**
 * Coveralls API options configuration
 */
interface CoverallsOptions {
  /** Always set to "." by the plugin */
  filepath: string;
  /** Repository token from config or environment */
  repo_token?: string;
  /** Additional options provided by coveralls.getBaseOptions() */
  [key: string]: any;
}

/**
 * Coveralls API methods used by the plugin
 */
interface CoverallsAPI {
  /** Gets base options including authentication from environment/config */
  getBaseOptions(callback: (err: Error | null, options: CoverallsOptions) => void): void;
  
  /** Converts LCOV format to Coveralls API format */
  convertLcovToCoveralls(
    lcovData: string,
    options: CoverallsOptions,
    callback: (err: Error | null, postData: any) => void
  ): void;
  
  /** Sends formatted data to Coveralls API */
  sendToCoveralls(
    postData: any,
    callback: (err: Error | null, response: CoverallsResponse, body: string) => void
  ): void;
}