Vue Unit Test Error: vuex requires a Promise polyfill in this browser
Asked Answered
S

3

17

I created a project using vue-cli and added vuex and vue-router in it. I am trying to setup a unit test for it, but I am getting following error. Without Vuex, it used to work.

PhantomJS 2.1.1 (Mac OS X 0.0.0) ERROR

Error: [vuex] vuex requires a Promise polyfill in this browser.

at webpack:///~/vuex/dist/vuex.js:145:0 <- index.js:9871

The following are the relevant package versions:

"babel-core": "^6.0.0",
"babel-eslint": "^7.0.0",
"babel-loader": "^6.0.0",
"vue": "^2.1.0",
"vue-router": "^2.0.3",
"vuex": "^2.0.0",
"vuex-router-sync": "^3.0.0"
"karma": "^1.3.0",
"karma-coverage": "^1.1.1",
"karma-mocha": "^1.2.0",
"karma-phantomjs-launcher": "^1.0.0",
"karma-sinon-chai": "^1.2.0",
"karma-sourcemap-loader": "^0.3.7",
"karma-spec-reporter": "0.0.26",
"karma-webpack": "^1.7.0",
"webpack": "^1.13.2",
"webpack-dev-middleware": "^1.8.3",
"webpack-hot-middleware": "^2.12.2",
"webpack-merge": "^0.14.1"

The following is karma.conf.js:

// This is a karma config file. For more details see
//   http://karma-runner.github.io/0.13/config/configuration-file.html
// we are also using it with karma-webpack
//   https://github.com/webpack/karma-webpack

var path = require('path')
var merge = require('webpack-merge')
var baseConfig = require('../../build/webpack.base.conf')
var utils = require('../../build/utils')
var webpack = require('webpack')
var projectRoot = path.resolve(__dirname, '../../')

var webpackConfig = merge(baseConfig, {
  // use inline sourcemap for karma-sourcemap-loader
  module: {
    loaders: utils.styleLoaders()
  },
  devtool: '#inline-source-map',
  vue: {
    loaders: {
      js: 'isparta'
    }
  },
  plugins: [
    new webpack.DefinePlugin({
      'process.env': require('../../config/test.env')
    })
  ]
})

// no need for app entry during tests
delete webpackConfig.entry

// make sure isparta loader is applied before eslint
webpackConfig.module.preLoaders = webpackConfig.module.preLoaders || []
webpackConfig.module.preLoaders.unshift({
  test: /\.js$/,
  loader: 'isparta',
  include: path.resolve(projectRoot, 'src'),
  exclude: /test\/unit|node_modules/
})

// only apply babel for test files when using isparta
webpackConfig.module.loaders.some(function (loader, i) {
  if (loader.loader === 'babel') {
    loader.include = path.resolve(projectRoot, 'test/unit')
    return true
  }
})

module.exports = function (config) {
  config.set({
    // to run in additional browsers:
    // 1. install corresponding karma launcher
    //    http://karma-runner.github.io/0.13/config/browsers.html
    // 2. add it to the `browsers` array below.
    browsers: ['Chrome'],
    frameworks: ['mocha', 'sinon-chai'],
    reporters: ['spec', 'coverage'],
    files: ['./index.js'],
    preprocessors: {
      './index.js': ['webpack', 'sourcemap']
    },
    webpack: webpackConfig,
    webpackMiddleware: {
      noInfo: true
    },
    coverageReporter: {
      dir: './coverage',
      reporters: [
        { type: 'lcov', subdir: '.' },
        { type: 'text-summary' }
      ]
    }
  })
}
Shipe answered 24/11, 2016 at 10:42 Comment(0)
S
26

Using Babel polyfill solved the problem. Here are the steps what I did:

Installing Babel Polyfill:

npm install --save-dev babel-polyfill

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'
],
Shipe answered 24/11, 2016 at 10:57 Comment(5)
Ahem... What is I don't have a karma file? I installed babel-polyfill but the issue saying vuex requires a Promise polyfill in this browser remains. Should I add it to webpack.config.js?Debi
@KonradViltersten : that path should be '../../node_modules/babel-polyfill/dist/polyfill.js'Whatsoever
@paritosh I can't see the difference between the suggested path and the one that I see in the answer. What do I miss?Debi
@KonradViltersten : I meant that path should be relative path to polyfill.js,Whatsoever
so ../ should be ../../Whatsoever
C
22

If you think babel-polyfill is too big, you could just include the es6-promise polyfill:

files: [
  '../node_modules/es6-promise/dist/es6-promise.auto.js',
  'index.js'
],

On the other hand, if you are not sure whether your site visitors' browsers have built-in Promise support, you could include the polyfill in your entry fill, main.js:

import 'es6-promise/auto'

EDIT:

Good news! Chrome can run in headless mode since version 59. So you could run your unit tests in headless Chrome now instead of PhantomJS.

For vue-cli/webpack generated projects, you could follow these steps:

  • Install karma-chrome-launcher via npm or yarn.
  • You could also remove karma-phantomjs-launcher, karma-phantomjs-shim, phantomjs-prebuilt from your project. They are for PhantomJS.
  • In test/unit/karma.conf.js, change browsers field to ['ChromeHeadless'], and remove 'phantomjs-shim' from frameworks field.

Here's my karma.conf.js, no polyfill anymore:

var webpackConfig = require('../../build/webpack.test.conf')

module.exports = function(config) {
  config.set({
    // to run in additional browsers:
    // 1. install corresponding karma launcher
    //    http://karma-runner.github.io/0.13/config/browsers.html
    // 2. add it to the `browsers` array below.
    browsers: ['ChromeHeadless'],
    frameworks: ['mocha', 'sinon-chai'],
    reporters: ['spec', 'coverage'],
    files: ['./index.js'],
    preprocessors: {
      './index.js': ['webpack', 'sourcemap']
    },
    webpack: webpackConfig,
    webpackMiddleware: {
      noInfo: true
    },
    coverageReporter: {
      dir: './coverage',
      reporters: [
        { type: 'lcov', subdir: '.' },
        { type: 'text-summary' }
      ]
    }
  })
}

The reason to do so:

  1. Chrome 59 is the latest stable release, it supports most ES6 features, even some from ES7/8, without polyfill.
  2. PhantomJS hasn't been updated since about 18 months ago. It doesn't support many new features since ES specs are moving so fast.
  3. The author of PhantomJS has announced to discontinue.
Creation answered 10/1, 2017 at 5:40 Comment(0)
P
0

my application was created with webpack and the only way i found to load my application in internet explorer and stop this error was to put this script in the head of my index.html


    <!-- Script for polyfilling Promises on IE9 and 10 -->
    <script src='https://cdn.polyfill.io/v2/polyfill.min.js'></script>

I hope to help.

Perch answered 15/9, 2020 at 15:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.