One Test Run, Multiple Browsers: Catching Cross-Browser Bugs with Karma
Karma can run your JavaScript unit tests in several real browsers at once and merge the results into a single report. Here is how to configure it, what to expect, and when to scale back parallelism.
12 Aug 2025, 02:02 UTC

The "works on my machine" trap
You write a unit test, it passes locally, and CI goes green. Then a bug report arrives: the feature is broken for Firefox users, or Safari throws an unexpected error. The test suite did its job in one browser, but it never exercised the code path in the environment where the failure actually occurs. The gap is not the test logic; it is the missing browser coverage.
Karma's built-in multi-browser execution
Karma is a test runner that starts real browser instances, loads your test bundle, and collects results over a socket connection. Unlike runners that simulate a DOM, Karma drives actual Chrome, Firefox, or Safari processes. Its configuration file, karma.conf.js, accepts a browsers array. When you list more than one browser, Karma launches them in parallel and merges their pass/fail counts into a single summary. No extra plugins are required for this behavior.
The concurrency setting controls how many browser instances run at the same time. If you omit it, Karma uses a default that may spawn every listed browser simultaneously. On a developer laptop that is usually fine; on a constrained CI agent it can exhaust memory.
A practical configuration
Assume you have Karma installed in a project and want to run the same Jasmine suite in headless Chrome and Firefox. Your karma.conf.js might look like this:
module.exports = function(config) {
config.set({
frameworks: ['jasmine'],
files: ['test/**/*.js'],
browsers: ['ChromeHeadless', 'Firefox'],
concurrency: 2,
singleRun: true,
reporters: ['progress']
});
};
Run it from the project root—the directory containing karma.conf.js—with:
karma start
For a CI pipeline where the process must exit after one pass, use:
karma start --single-run
You need Node.js and the Karma CLI available. Both browsers must be installed and reachable on the machine. On Linux, non-headless browsers may require a display server; headless variants run without a visible window and avoid that dependency, which is why they are preferred for automated runs.
What to expect in the terminal
When the run begins, Karma prints a line for each browser as it connects, typically including the browser name and a socket identifier. You should see entries indicating that ChromeHeadless and Firefox have connected. As tests execute, the progress reporter shows activity. At the end, Karma prints a combined summary: total specs, failures, and a per-browser breakdown. If a test fails only in Firefox, the failure appears under the Firefox section, not under Chrome.
To verify that the separation works, temporarily add a test that asserts on a browser-specific global—something that exists in one browser but not the other. Run the suite again. The failure should appear only in the section for the browser that lacks that global. Remove the temporary test once confirmed.
The resource trade-off
Parallel browsers are useful, but they are not free. Each browser process consumes CPU and memory, and headless modes reduce overhead without eliminating it. In containerized CI environments with tight memory limits, launching four browsers at once can cause timeouts or flaky failures that have nothing to do with your code.
If you see intermittent timeouts or out-of-memory kills, lower concurrency to 1 or 2, or split browser targets across separate CI jobs. A slower but stable run is better than a fast one that fails randomly.
Actionable takeaways
- List every browser you support in the
browsersarray; do not rely on a single default. - Set
concurrencyexplicitly based on your CI agent's resources, not just your local machine. - Use
--single-runin CI so the process exits cleanly. - Confirm browser separation by introducing a deliberate browser-specific failure and checking the report.
Karma's multi-browser support does not require a new tool or a complex pipeline. It requires a small configuration change and an awareness of the resource cost. Start with two browsers, verify the output, and scale only when your infrastructure can handle it.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.