CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-karma-coveralls

A karma plugin which uploads coverage reports to coveralls.io

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

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;
}
Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/karma-coveralls@2.1.x
Publish Source
CLI
Badge
tessl/npm-karma-coveralls badge