Configuring Karma for Headless CI/CD Execution
Learn how to configure Karma for headless browser execution in CI/CD pipelines, including the essential ChromeHeadless setup and CHROME_BIN environment variables.
09 Feb 2026, 22:49 UTC

Solving the Browser Execution Gap in CI
The primary challenge when moving JavaScript unit tests from a local machine to a CI/CD pipeline is the lack of a graphical user interface (GUI). Standard browser launchers attempt to open a visible window, which causes the test suite to crash in headless environments like GitHub Actions, GitLab CI, or Jenkins.
The solution is to configure Karma to use Headless mode—a browser state where the engine runs without a visible UI—and ensure the runner can locate the browser binary via environment variables.
How Karma Orchestrates Tests
Karma is a test runner, not a testing framework. It does not provide assertions (like expect) or test suites (like describe); instead, it acts as a proxy server. It spawns a web server, launches one or more real browsers, injects your test files into those browsers, and captures the results via Socket.io to report them back to your terminal.
Worked Configuration: Headless Chrome
To run tests in a CI environment, you must use a launcher like karma-chrome-launcher and set the browser to ChromeHeadless. Below is a production-ready karma.conf.js configuration.
module.exports = function(config) {
config.set({
// Frameworks define the assertion library used
frameworks: ['jasmine'],
// Files to be loaded in the browser
files: [
'src/**/*.js',
'test/**/*.spec.js'
],
// Use ChromeHeadless for CI; Chrome for local development
browsers: ['ChromeHeadless'],
// singleRun: true ensures the process exits after tests finish
// This is critical for CI pipelines to avoid hanging builds
singleRun: true,
reporters: ['progress'],
// Custom launcher configuration to handle Linux sandbox issues
customLaunchers: {
ChromeHeadlessCI: {
base: 'ChromeHeadless',
flags: ['--no-sandbox', '--disable-setuid-sandbox']
}
}
});
};
Running the Tests
Execute the tests from your project root using the following command. Ensure you have the necessary permissions to execute binaries in your environment.
# Install dependencies first
npm install karma karma-jasmine karma-chrome-launcher jasmine-core --save-dev
# Run Karma
npx karma start
Expected Result: The terminal should indicate ChromeHeadless 12X.X.X (Windows/Linux) started, followed by the number of executed specs and a final Executed X of X summary. If the process does not exit, check that singleRun is set to true.
Critical CI Environment Adjustments
In many CI environments, Karma may fail to find the Chrome binary automatically. You must explicitly define the path to the browser executable using the CHROME_BIN environment variable.
Example for Linux-based CI:
# Set the path to the installed Chrome binary before running tests
export CHROME_BIN=/usr/bin/google-chrome
npx karma start
Common Pitfalls and Limitations
- The Sandbox Error: On Linux servers, Chrome often fails to launch due to namespace restrictions. Using the
--no-sandboxflag incustomLaunchersis the standard workaround, though it should be used only in trusted CI environments. - Version Mismatch: If the
karma-chrome-launcherversion is significantly older than the installed Chrome browser, the Socket.io connection may drop, leading toDisconnectederrors in the console. Keep your npm packages updated. - Memory Leaks: When running very large test suites in headless mode, the browser process may consume excessive RAM. If the build crashes with an
Out of Memoryerror, consider splitting tests into multiple smaller suites.
Verification and Rollback
To verify the configuration is working, run the tests locally using browsers: ['Chrome'] first to ensure the logic is sound, then switch to ChromeHeadless to verify the runner's ability to execute without a GUI.
Rollback: Since this configuration only changes the karma.conf.js file and environment variables, rollback involves reverting the browsers array to your previous setting (e.g., ['Chrome']) and removing the CHROME_BIN export from your shell profile.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.