Command-line tool for running browser-based tests locally in a headless environment
npx @tessl/cli install tessl/npm-testling@1.7.0Testling is a command-line tool for running browser-based tests locally in a headless environment. It provides the same functionality as the testling-ci service, allowing developers to test browser JavaScript code locally with TAP (Test Anything Protocol) output and proper exit codes for CI/CD integration.
npm install -g testlingFor the single programmatic API:
const unglob = require('testling/lib/unglob');Primary usage is through the command-line interface:
# Run tests from package.json testling configuration
testling
# Run tests from stdin
browserify test.js | testling
# Run tests from specific directory
testling ./test-directory
# Generate HTML output instead of running browser
testling --html
# Print URL instead of launching browser
testling -u
# Use custom browser command
testling -x "chromium --headless"Example test file setup:
// test.js
var test = require('tape');
test('example test', function (t) {
t.plan(2);
t.equal(1+1, 2);
t.ok(true);
});Example package.json configuration:
{
"testling": {
"files": ["test/*.js"],
"scripts": ["lib/*.js"],
"browsers": ["chrome/latest", "firefox/latest"],
"harness": "tape"
}
}Testling operates through several key components:
testling commandPrimary interface for running browser tests locally with various configuration options.
testling {DIRECTORY|-} {OPTIONS}
# OPTIONS:
# --html Generate HTML output instead of launching browser
# --no-show Disable console.log() rendering to document body
# -u Print URL instead of launching browser
# -x COMMAND Launch browser with explicit command
# --bcmd COMMAND Alias for -x (launch browser with explicit command)
# --host HOST Set hostname (default: localhost)
# --port PORT Set port number
# --harness HARNESS Override test harness from package.json
# -h, --help Show help textInput Sources:
Output: TAP (Test Anything Protocol) formatted results to stdout with proper exit codes (0 for success, 1 for failure)
Utility function for expanding glob patterns from testling configuration into resolved file paths.
/**
* Expands glob patterns from testling configuration into resolved file paths
* @param {string} dir - Base directory path
* @param {Object} params - Configuration object with file/script glob patterns
* @param {Array|string} params.files - Glob patterns for files to browserify
* @param {Array|string} params.scripts - Glob patterns for script files
* @param {Function} callback - Callback function (err, expanded)
* @returns {void}
*/
function unglob(dir, params, callback);Callback Result:
interface ExpandedFiles {
file: string[]; // Resolved file paths for browserifying
script: string[]; // Resolved script file paths
postScript: string[]; // Reserved for post-script files (unused)
}Usage Example:
const unglob = require('testling/lib/unglob');
const params = {
files: ['test/*.js', 'spec/*.js'],
scripts: ['lib/*.js']
};
unglob('/path/to/project', params, function(err, expanded) {
if (err) throw err;
console.log('Files to browserify:', expanded.file);
console.log('Script files:', expanded.script);
});Configuration through package.json "testling" field for test setup and browser specifications.
interface TestlingConfig {
/** Glob patterns for files to browserify and test */
files?: string | string[];
/** Script files to include directly in HTML */
scripts?: string | string[];
/** Custom HTML template file path */
html?: string;
/** Browser specifications (primarily for CI, not used locally) */
browsers?: string[];
/** Custom server command to run alongside tests */
server?: string;
/** Build command to run before testing */
preprocess?: string;
/** Test harness specification (e.g., "mocha-bdd", "tape") */
harness?: string;
}Configuration Examples:
{
"testling": {
"files": ["test/*.js"],
"harness": "tape"
}
}{
"testling": {
"files": ["test/**/*.test.js"],
"scripts": ["vendor/jquery.js"],
"html": "test/custom.html",
"harness": "mocha-bdd",
"preprocess": "npm run build"
}
}Support for multiple test harnesses with automatic detection and TAP output generation.
// Supported harness values:
// "tape" - Default/automatic detection
// "mocha-bdd" - Mocha with BDD interface
// "mocha-tdd" - Mocha with TDD interface
// "mocha-qunit" - Mocha with QUnit interface
// Custom harnesses via configurationHarness Detection:
TAP Output: All supported frameworks generate TAP (Test Anything Protocol) formatted output with proper test counts, assertions, and failure details.
Testling handles various error conditions with appropriate exit codes and error messages:
When tests run in the browser, testling creates a Node.js-like environment:
// Global objects available in browser:
interface BrowserGlobals {
/** Modified console object for test output */
__testlingConsole: Console;
/** Error handler function */
__testlingErrorHandler: Function;
}
// Mock Node.js objects:
interface MockProcess {
stdout: WritableStream; // Stream for test output
stderr: WritableStream; // Stream for error output
exit: Function; // Function to end test execution
on: Function; // No-op function
}Testling requires several external tools and packages:
External Requirements:
Note: The package.json specifies "browserify": "browser.js" but this file doesn't exist; the actual browser prelude is at browser/prelude.js.
Runtime Dependencies:
@tapjs/tap-finished - TAP result parsingbouncy - HTTP proxy serverbrowser-launcher - Browser detection/launchingbrowserify - JavaScript bundlingconcat-stream - Stream concatenationcross-spawn - Cross-platform process spawningecstatic - Static file serverglob - File pattern matchingoptimist - Command-line argument parsing-x option