56

I'm trying to run Karma/Jasmine from Grunt on a project generated with http://newtriks.com/2013/12/31/automating-react-with-yeoman-and-grunt/

Karma launches PhantomJS (or Chrome) and, depending on singleRun, it either times out or just sits there and does nothing. I've tried changing captureTimeout and browserNoActivityTimeout based on reading solutions from people with similar problems, but it doesn't seem to work.

My relevant pacakge versions etc.:

  • NodeJS: 0.10.25
  • Karma: 0.12.16
  • Webpack: 1.1.11
  • webpack-dev-server: 1.4.1
  • karma-jasmine: 0.1.5
  • Linux: Ubuntu 14.04

I've found someone with the same problem on OS X:

I've tried updating all my dev dependencies to the latest versions but the problem still remains.

My console output is below. The webpack lines referring to bundle is now VALID/INVALID are worrying, but I can't find any info on what they mean. Here's my console output:

Running "karma:unit" (karma) task
DEBUG [config]: autoWatch set to false, because of singleRun
DEBUG [plugin]: Loading karma-* from /home/ed/workspace/wwb-app/node_modules
DEBUG [plugin]: Loading plugin /home/ed/workspace/wwb-app/node_modules/karma-chrome-launcher.
DEBUG [plugin]: Loading plugin /home/ed/workspace/wwb-app/node_modules/karma-coffee-preprocessor.
DEBUG [plugin]: Loading plugin /home/ed/workspace/wwb-app/node_modules/karma-firefox-launcher.
DEBUG [plugin]: Loading plugin /home/ed/workspace/wwb-app/node_modules/karma-html2js-preprocessor.
DEBUG [plugin]: Loading plugin /home/ed/workspace/wwb-app/node_modules/karma-jasmine.
DEBUG [plugin]: Loading plugin /home/ed/workspace/wwb-app/node_modules/karma-phantomjs-launcher.
DEBUG [plugin]: Loading plugin /home/ed/workspace/wwb-app/node_modules/karma-requirejs.
DEBUG [plugin]: Loading plugin /home/ed/workspace/wwb-app/node_modules/karma-script-launcher.
DEBG [plugin]: Loading plugin /home/ed/workspace/wwb-app/node_modules/karma-webpack-plugin.
INFO [karma]: Karma v0.12.16 server started at  http://localhost:8080/
INFO [launcher]: Starting browser PhantomJS
DEBUG [temp-dir]: Creating temp dir at /tmp/karma-98204612
DEBUG [launcher]: /home/ed/workspace/wwb-app/node_modules/karma-phantomjs-launcher/node_modules/phantomjs/lib/phantom/bin/phantomjs /tmp/karma-98204612/capture.js
Hash: 89285186567c1bc5bb7f
Version: webpack 1.1.11
Time: 2ms
Asset  Size  Chunks       Chunk Names
webpack: bundle is now VALID.
webpack: bundle is now INVALID.
DEBUG [web-server]: serving: /home/ed/workspace/wwb-app/node_modules/karma/static/client.html
DEBUG [web-server]: serving: /home/ed/workspace/wwb-app/node_modules/karma/static/karma.js
DEBUG [web-server]: upgrade /socket.io/1/websocket/CjC8pnQq5It2z_kWYB98
DEBUG [karma]: A browser has connected on socket CjC8pnQq5It2z_kWYB98
INFO [PhantomJS 1.9.7 (Linux)]: Connected on socket CjC8pnQq5It2z_kWYB98 with id 98204612
DEBUG [launcher]: PhantomJS (id 98204612) captured in 1.704 secs
WARN [PhantomJS 1.9.7 (Linux)]: Disconnected (1 times), because no message in 30000 ms.

DEBUG [karma]: Run complete, exitting.
DEBUG [launcher]: Disconnecting all browsers
DEBUG [launcher]: Process PhantomJS exited with code 0
DEBUG [temp-dir]: Cleaning temp dir /tmp/karma-98204612
Warning: Task "karma:unit" failed. Use --force to continue.

Aborted due to warnings.

Here's my karma.conf.js file:

'use strict';

module.exports = function (config) {
config.set({
    basePath: '',
    frameworks: ['jasmine'],
    files: [
        'test/helpers/**/*.js',
        'test/spec/components/**/*.js'
    ],
    preprocessors: {
        'test/spec/components/**/*.js': ['webpack']
    },
    webpack: {
        cache: true,
        module: {
            loaders: [{
                test: /\.css$/,
                loader: 'style!css'
            }, {
                test: /\.gif/,
                loader: 'url-loader?limit=10000&minetype=image/gif'
            }, {
                test: /\.jpg/,
                loader: 'url-loader?limit=10000&minetype=image/jpg'
            }, {
                test: /\.png/,
                loader: 'url-loader?limit=10000&minetype=image/png'
            }, {
                test: /\.js$/,
                loader: 'jsx-loader'
            }]
        }
    },
    webpackServer: {
        stats: {
            colors: true
        }
    },
    exclude: [],
    port: 8080,
    logLevel: config.LOG_DEBUG,
    colors: true,
    autoWatch: true,
    // Start these browsers, currently available:
    // - Chrome
    // - ChromeCanary
    // - Firefox
    // - Opera
    // - Safari (only Mac)
    // - PhantomJS
    // - IE (only Windows)
    browsers: ['PhantomJS'],
    reporters: ['progress'],
    captureTimeout: 60000,
    browserNoActivityTimeout: 60000,
    singleRun: true
});
};
Community
  • 1
  • 1
edoloughlin
  • 5,821
  • 4
  • 32
  • 61

14 Answers14

50

I had the same problem. From a related GitHub Issue, I learned that you can extend the inactivity timeout.

Set this Karma config option in your gruntfile or karma config file:

browserNoActivityTimeout: 100000

I set it to 100 seconds and my tests ran successfully. I don't know what's causing the delay.

Matthias
  • 13,607
  • 9
  • 44
  • 60
  • 2
    I tried playing around with timeouts without success. Nothing worked while karma was installed globally – edoloughlin Jul 22 '14 at 17:34
  • 10
    `webpack-dev-middleware`, used under `webpack-karma`'s hood, compiles the assets only once a browser requests the files. Therefore, *after* the browser has loaded the karma test page, compilation begins, only after which the browser will respond to Karma. Production compilation takes 30~45 seconds for my project. – Tom McKenzie May 18 '15 at 01:16
  • 2
    I thought many times to have solved the problem, but each time I was wrong, sometimes it works, another time it doesnt. Tried to play with timeouts as well, browser options to make it as lightweight as possible (chrome headless, no-plugin, no translation files, ...) tried to free my machine from every other Chrome processes, also tried with at least approximately 6 GB of available RAM, tried other karma versions ... each time it happens, sometimes, somehow. – Alex Jul 02 '19 at 10:08
34

I've changed my Karma config, to

captureTimeout: 60000, // it was already there
browserDisconnectTimeout : 10000,
browserDisconnectTolerance : 1,
browserNoActivityTimeout : 60000,//by default 10000

Also I have 200-300 tests, PhantomJS 1.9.8 and it needs only about 100 mb memory for Phantom With grunt and karma They all together used about 300mb of memory.

Anatoli Klamer
  • 2,279
  • 2
  • 17
  • 22
16

We encountered a similar problem on our build servers.

Increasing the browserNoActivityTimeout worked to a point. We upped it to 60000ms, but the problem with phantomJS not disconnecting returned as the number of unit tests increasing.

We eventually tracked the problem down to the RAM available to phantomJS. We had 1100 unit tests that would take ~1m30s to run, but phantomJS would fail to disconnect within the 60000ms timeout.

The build node VM RAM was increased from 2GB to 4GB and the 1100 unit tests then took ~45s to run and phantomJS would disconnect with ~5s. A huge improvement.

There are two lessons: 1. PhantomJS is memory hungry, so make sure it has enough RAM to do its thing 2. Profile your code to learn where you can be more efficient with memory usage.

Gareth
  • 161
  • 1
  • 2
  • It seems you can use `browserNoActivityTimeout: 0`, and this seems to make it wait longer. Does Karma wait forever at this point or is there a limit? This is not well documented on `karma-runner.github.io` and google is not helping elsewhere, either. – trysis Apr 17 '15 at 20:44
  • 15
    Where and how (what settings) do you up the RAM for phantomJS? – Nick Sep 22 '15 at 17:11
  • @Nick He said - by increasing the RAM allocated to his VM. Phantom itself has no memory limit. – JShorthouse Jun 03 '19 at 14:39
7

Another likely explanation is RequireJS getting in the way. I'm getting this exact error if I add 'requirejs' to the karma.conf.js in the config.frameworks array. This seems to override the native require function and cause tests to not be executed. In my case the describe-block was triggered, but none if the it-blocks were.

Micros
  • 5,966
  • 2
  • 28
  • 34
4

In my case I hadn't included the following code in my test.js file:

requirejs.config({
    callback: window.__karma__.start
});

describe('tests', function() {
    ...

Once this config was included the tests started running. Hopefully this saves someone else a lot of stress!

garryp
  • 5,508
  • 1
  • 29
  • 41
3

Remove the 'requires' from the karma config file, just use frameworks: ['jasmine'].

2

Check that localhost points correctly to 127.0.0.1 and not an unreachable IP, this can happen in dev environments using virtual machines for example.

eloone
  • 4,248
  • 2
  • 32
  • 35
1

This may not be the case for the OP here, but if the code you're testing hits an infinite loop, it will cause a disconnection on timeout just like this.

Todd Sjolander
  • 1,459
  • 1
  • 15
  • 28
1

Here is why I was getting this error, might help someone in similar situation. My main component had multiple child components which were using different services, one of the services had an HTTP call and the initialisation failed as I was using that service in ngInit() method of the child component. To fix the issue, I had to import the above service in the main component specs and attach a mock for the service, it started working after that.

Vijender
  • 11
  • 1
1

Set pingTimeout: 10000 into karma browser config solves the issue for me, like this:

browsers: ['Chrome', 'ChromeHeadlessNoSandbox'],
  customLaunchers: {
      ChromeHeadlessNoSandbox: {
        base: 'ChromeHeadless',
        flags: ['--no-sandbox'],
        browserNoActivityTimeout: 10000,
        browserDisconnectTimeout: 10000,
        pingTimeout: 10000
   }
},
Carla C
  • 79
  • 5
0

I solved this for my own environment. I had a bunch of nodejs packages installed globally. I didn't do a regression to figure out exactly what package caused the problem, but I strongly suspect that having karma installed globally was the cause.

If you have this problem then try

sudo npm -g remove karma

and if that doesn't work then I would remove all global node packages (except truly global packages like yeoman, grunt-cli, for example). And then install locally for your project.

I also noticed that when you run sudo npm -i on OS X, it changes the owner of ~/.npm to root and subsequent npm -i commands will fail with an EACCESS error,.

edoloughlin
  • 5,821
  • 4
  • 32
  • 61
0

@Vijender's answer got me on the right track

It was as simple as replacing HttpClientModule in tests with HttpClientTestingModule.

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        HttpClientTestingModule
      ]
    }).compileComponents();
  }));
Vedran
  • 10,369
  • 5
  • 50
  • 57
0

I fixed this by removing a call to an async function at global scope, in my Root.tsx.

It was working in a 'real' browser window, but doesn't work in a test run.

It seems to make loading the module itself hang, so it doesn't even get as far as executing the async function (so log statements won't show up)

Edit: This was caused by another async function, run at app startup, that was trying to do auth and redirect to another URL. That's why it worked in the browser but not in headless mode. Without any async test functions, the auth code never had a chance to jam the system. With an async test, the async auth code started running and caused the lock-up.

Moral of the story: if an async test is hanging, check what other async code is going on in the background.

0
afterEach(function () {
    document.body.innerHTML = '';
});

Adding this fixed issue for me, tests started running much faster. Seems like it decreases load on headless browser.