39

I am writing a JavaScript library that uses the new es6 promises. I can test the library in Firefox because promises are defined. However, when I try to test my code with Karma and PhantomJS, I get the error Can't find variable: Promise.. I am guessing this is because the PhantomJS browser doesn't support es6 promises yet.

How can I configure Karma to bring in the polyfill for promises?

Travis Parks
  • 8,435
  • 12
  • 52
  • 85

5 Answers5

73

You can pull in the Babel polyfill by simply installing Babel Polyfill:

npm install --save-dev babel-polyfill

and then include the polyfill file before your source and test files within the files section of your karma.conf.js:

files: [
  'node_modules/babel-polyfill/dist/polyfill.js',
  'index.js',   //could be /src/**/*.js
  'index.spec.js' //could be /test/**/*.spec.js
],

Unless you know that all your target browsers support Promises, you probably want to apply this polyfill to your released build too.

If you're feeling really adventurous you can use Browserify to pull files in to make your testing more modular, and then use Babelify to transpile ES6 to ES5. I've created a sample project with these and a working test involving a Promise (running on PhantomJS2) for reference.

Nathan Tuggy
  • 2,237
  • 27
  • 30
  • 38
spikeheap
  • 3,827
  • 1
  • 32
  • 47
  • I'm having a similar issue but after including the polyfill, the Promise never seems to resolve, here's a gist: https://gist.github.com/Kikketer/1646eccdaff76944b358 Anyone have a clue why the Promise would never run it's '.then' ? – Chris Feb 19 '16 at 17:47
  • 1
    @Chris your problem doesn't look at all related. I couldn't run your gist, but it looks like you're problem is probably related to Angular. Don't use the Promise polyfill with Angular – you need to use the built-in $q implementation (otherwise it won't work with the digest cycle). If you want to build a resolved promise use `$q.when(some_object)`. You really need to open a new question on SO, but post the link here and I'll take a look. – spikeheap Feb 20 '16 at 18:44
  • @spikeheap yea I switched to $q throughout the app and it worked. Thanks for looking at it. – Chris Feb 21 '16 at 22:05
  • Shouldn't using https://github.com/webpack/karma-webpack with babel and having its configuration section in karma.conf.js as well as the `proprocessor: { './tests/**/*.js', : [ 'webpack' ] }` be enough? Why would I **also** have to add the polyfill manually, when webpack adds it in normal circumstances? – Henrik Apr 30 '16 at 11:30
  • Hi @Henrik, it sounds like you've answered your own question ;). This question/answer is useful for the huge number of people not using Webpack, but you're right: if you're using a system which is already polyfilling for you, don't manually add a polyfill. – spikeheap May 02 '16 at 11:48
  • I solved the same issue with using promise-polyfill: https://www.npmjs.com/package/promise-polyfill – Axel Meier Aug 31 '16 at 15:05
13

For Babel 6, we need install babel-polyfill to support promise.

npm install --save-dev babel-polyfill

and add a line in karma.conf.js within the files section

files: [
  'node_modules/babel-polyfill/dist/polyfill.js',
  ....
]

It's well documented in https://github.com/babel/karma-babel-preprocessor#polyfill

Artjom B.
  • 61,146
  • 24
  • 125
  • 222
gasolin
  • 2,196
  • 1
  • 18
  • 20
1

as correctly pointed out by the author it is not able to recognize es6 promise. In order to load it, es6-promise module can be loaded with the help of webpack.ProvidePlugin and configuring it inside plugins array of webpack.

plugins: [
        new webpack.ProvidePlugin({
            'Promise': 'es6-promise'
        })
    ]

This seems to work for me!

Manit
  • 1,087
  • 11
  • 17
0

This thread should help you. According to it, it seems you should try to use PhantomJS2 with ES6. You can also take a look to this project, which treat to the a near subject than yours.

I hope it may help you

Tony
  • 482
  • 4
  • 13
0

You can use karma-babel-preprocessor for files that uses ES6 features. Install it with

npm install --save-dev karma-babel-preprocessor

and then add specify what files should be preprocessed you karma.conf:

preprocessors: {
      "src/**/*.js": ["babel"],
      "test/**/*.js": ["babel"]
    },
SET001
  • 11,480
  • 6
  • 52
  • 76
  • Unfortunately this doesn't work. I was already using the `babel-preprocessor` and Karma couldn't find the `Promise.resolve()` function. The `babel-polyfill` fixed the issue for me. – Jelle den Burger Jan 19 '17 at 13:35