61

Using:

ng test

Angular CLI runs the tests by default in Chrome, which is great, but what if I need to run them in a console-only environment (headless browser)?

Also it would be nice if I can specify if I want browser-less or not each time I run it, so something like:

ng test --browsers MyHeadLessBrowser


Edit:

running PhantomJS I got the following:

PhantomJS 2.1.1 (Linux 0.0.0) ERROR TypeError: useValue,useFactory,data is not iterable! at http://localhost:9876/_karma_webpack_/polyfills.bundle.js:854


eferenceError: Can't find variable: Intl in http://localhost:9876/_karma_webpack_/vendor.bundle.js (line 49362) intlDateFormat@http://localhost:9876/_karma_webpack_/vendor.bundle.js:49362:20

isherwood
  • 46,000
  • 15
  • 100
  • 132
Francesco Borzi
  • 37,945
  • 31
  • 126
  • 195
  • A headless browser is running your browser without a browser UI, `PhantomJS` is a headless WebKit scriptable with a JavaScript API. `PhantomJS` is not maintained anymore because of the new headless options already available. – Claudiu Hojda Oct 12 '17 at 12:15

5 Answers5

96

As a more complete answer based on William Hampshire's one, Cuga's comment and my personal additions.


Short answer: using ChromeHeadless

You can just use Headless Chrome:

ng test --browsers ChromeHeadless

You need to have Chrome 59+.

But if you need PhantomJS (and/or chaning the default ng test behaviour with no arguments) read the following.


Longer answer: using PhantomJS

EDIT: Be aware that PhantomJS project has been archived, see this thread.

Setup

In order to be able to (optionally) run your tests without a browser, using PhantomJS, you should:

1) Install some dependencies:

npm install --save-dev karma-phantomjs-launcher
npm install --save intl

2) Add PhantomJS to the Karma's plugin list

Open karma.conf.js and add require('karma-phantomjs-launcher') to the plugins array, for example:

module.exports = function (config) {
  config.set({
    basePath: '',
    frameworks: ['jasmine', '@angular/cli'],
    plugins: [
      require('karma-jasmine'),
      require('karma-chrome-launcher'),
      require('karma-phantomjs-launcher'),
      // ...
    ],

3) Enable polyfills

Open your src/polyfills.ts file and uncomment the following lines:

BROWSER POLYFILLS

import 'core-js/es6/symbol';
import 'core-js/es6/object';
import 'core-js/es6/function';
import 'core-js/es6/parse-int';
import 'core-js/es6/parse-float';
import 'core-js/es6/number';
import 'core-js/es6/math';
import 'core-js/es6/string';
import 'core-js/es6/date';
import 'core-js/es6/array';
import 'core-js/es6/regexp';
import 'core-js/es6/map';
import 'core-js/es6/weak-map';
import 'core-js/es6/set';

APPLICATION IMPORTS

import 'intl';
import 'intl/locale-data/jsonp/en';

How to run the tests

Specifying the browsers when running the command

No you can either run the test using Chrome (the angular-cli default):

ng test --browsers Chrome

Or PhantomJS (headless):

ng test --browsers PhantomJS

Changing the default behaviour of just ng test

It is possible to change the default behaviour of ng test (so when no --browsers argument is provided) by changing the value of the browsers array in karma.conf.js.

It can now be set to just use Chrome (default angular-cli setup):

browsers: ['Chrome'],

or PhantomJS:

browsers: ['PhantomJS'],

or even both:

browsers: ['Chrome', 'PhantomJS'],

Francesco Borzi
  • 37,945
  • 31
  • 126
  • 195
  • 2
    Anybody reading this should be aware that development on PhantomJS has been suspended, see http://phantomjs.org/ , which is also why there is no support for ES6 yet (nor will there be unless development is continued) – seBaka28 Jul 03 '19 at 12:58
  • @FrancescoBorzi oh, true, totally skipped over that part ... well, I'll leave it for any other readers who are as lazy as me – seBaka28 Jul 04 '19 at 13:03
6

This should do the trick:

npm i --save-dev karma-phantomjs-launcher

Then modify the plugins property of the karma.conf.js file, adding the PhantomJS plugin to the list. Also add PhantomJS to the browsers property.

plugins: [
    require( 'karma-jasmine' ),
    require( 'karma-chrome-launcher' ),
    require( 'karma-phantomjs-launcher' ),
    require( 'karma-remap-istanbul' ),
    require( 'angular-cli/plugins/karma' )
],
...
browsers: [ 'PhantomJS', 'Chrome' ],

Since you want a completely headless experience, you can remove Chrome from the browsers property, and remove the karma-chrome-launcher from the plugins array as well.

William Hampshire
  • 4,967
  • 5
  • 29
  • 46
  • 2
    To add to William's answer, you can use the configuration he's provided and specify the 'non-UI' options on the command line / or on your build server with: `ng test --browsers PhantomJS` – Cuga Sep 25 '17 at 12:35
  • see the edit: Also it would be nice if I can specify if I want browser-less or not each time I run it, so something like – Francesco Borzi Sep 25 '17 at 12:36
  • If you have Chrome installed but just don't want it to pop-up, you can also specify "ChromeHeadless" as one of the browsers if you didn't want to use PhantomJS. – Cuga Sep 25 '17 at 12:36
  • 2
    @ShinDarth the options you could use are: `ng test --browsers Chrome` or `ng test --browsers ChromeHeadless` or `ng test --browsers PhantomJS` – Cuga Sep 25 '17 at 12:38
  • I am getting this error when using PhatomJs. { "message": "An error was thrown in afterAll\nTypeError: undefined is not an object (evaluating 'modules[moduleId].call')", "str": "An error was thrown in afterAll\nTypeError: undefined is not an object (evaluating 'modules[moduleId].call')" } – Philip Puthenvila Apr 26 '18 at 00:13
  • @PhilipPuthenvila you should open a new question for this issue – William Hampshire Apr 26 '18 at 11:19
4

Angular CLI provides all that we need to run tests without a browser.

Open the karma.conf.js file and add the ChromeHeadless to the browsers array -

browsers: ['ChromeHeadless'],

Happy testing!

Dmitry Grinko
  • 8,671
  • 12
  • 35
  • 63
1

If the purpose of running this headlessly is to get your code to run on a CI server, you will also likely want to set singleRun: true in your karma.conf.js. Without this Karma will run continuously, and time out.

0

Working Solution on Angular 11.

karma.conf.js

   browsers: ["ChromeHeadless"],
   singleRun: true

And then just run ng test or ng test --project=project_name.

This works in a CI environment too.

Note: This is a combination of two different answers here.

aneeshere
  • 339
  • 2
  • 14