vuejs / vue-cli

🛠️ webpack-based tooling for Vue.js Development
https://cli.vuejs.org/
MIT License
29.75k stars 6.33k forks source link

Jest tests can't process import statement #1584

Open ijdickinson opened 6 years ago

ijdickinson commented 6 years ago

Version

3.0.0-rc.2

Reproduction link

https://github.com/ijdickinson/vue-cli-jest-problem

Steps to reproduce

This is a similar problem to 1475, but I can't find a way to resolve it. I created a new app with vue-cli, selecting Jest tests. I added a simple POJO (src/models/model.js) and a test for it (tests/model.spec.js).

To repro the problem, just npm run test:unit

What is expected?

Tests to pass, or at least run

What is actually happening?

$ npm run test:unit

> test-application@0.1.0 test:unit /home/ian/workspace/project/test-application
> vue-cli-service test:unit

 FAIL  tests/unit/model.spec.js
  ● Test suite failed to run

    Jest encountered an unexpected token

    This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.

    By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".

    Here's what you can do:
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://facebook.github.io/jest/docs/en/configuration.html

    Details:

    /home/ian/workspace/project/test-application/tests/unit/model.spec.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import "core-js/modules/es6.promise";
                                                                                             ^^^^^^

    SyntaxError: Unexpected token import

      at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:402:17)

 PASS  tests/unit/HelloWorld.spec.js

Test Suites: 1 failed, 1 passed, 2 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        1.427s
Ran all test suites.
 ERROR  jest exited with code 1.
LinusBorg commented 5 years ago

And the Babel config? Also: are you sure you don't have any dependencies that use es6 modules? As jest ignores node_modules by default, those would never be transpiled.

As a sidenote: your dependencies look a bit as if you tried to integrate plugin of vue-cli 3 into an old webpack template from vue-cli 2. There's probably dozen chances for conflicts and things to go wrong.

Would have been good to know you aren't on a greenfield project...

komali2 commented 5 years ago

@LinusBorg

babel.config.js

module.exports = {
    presets: [
        '@vue/app'
    ]
}

thanks for sticking with me :)

LinusBorg commented 5 years ago

Looking fine as well :-/

Last straw: do you have any suspicious env variables set on it system? Check printenv, e.g. for NODE_ENV or any VUECLI* variables

komali2 commented 5 years ago

Nope :(

komali2 commented 5 years ago

I should note, it's not working on any machine in this office...

msurdi commented 5 years ago

I was getting the same error message, I fixed this by adding to my package.json:

...
+  "@babel/core": "^7.1.2",
+  "@babel/preset-env": "^7.1.0",
...
+  "babel": {
+    "presets": [
+      "@babel/preset-env",
+      [
+        "@vue/app",
+        {
+          "useBuiltIns": "entry"
+        }
+      ]
+    ]
+  },
...

Also, I've removed the babel.config.js file.

Hope this helps to find the root cause.

LinusBorg commented 5 years ago

@msurdi our babel-preset wraps preset-env, so adding it should have no effect. If it has, then its ab out an option that we can set on our preset as well.

komali2 commented 5 years ago

@msurdi this causes the following error:

  ● Test suite failed to run

    Requires Babel "^7.0.0-0", but was loaded with "6.26.3". If you are sure you have a compatible version of @babel/core, it is likely that something in your build process is loading the wrong version. Inspect the stack trace of this error to look for the first entry that doesn't mention "@babel/core" or "babel-core" to see what is calling Babel. (While processing preset: "/example/node_modules/@babel/preset-env/lib/index.js")

      at throwVersionError (node_modules/@babel/preset-env/node_modules/@babel/helper-plugin-utils/lib/index.js:65:11)
      at Object.assertVersion (node_modules/@babel/preset-env/node_modules/@babel/helper-plugin-utils/lib/index.js:13:11)
      at _default (node_modules/@babel/preset-env/lib/index.js:154:7)
      at node_modules/@babel/preset-env/node_modules/@babel/helper-plugin-utils/lib/index.js:19:12
      at node_modules/babel-core/lib/transformation/file/options/option-manager.js:317:46
          at Array.map (<anonymous>)
      at OptionManager.resolvePresets (node_modules/babel-core/lib/transformation/file/options/option-manager.js:275:20)
      at OptionManager.mergePresets (node_modules/babel-core/lib/transformation/file/options/option-manager.js:264:10)
      at OptionManager.mergeOptions (node_modules/babel-core/lib/transformation/file/options/option-manager.js:249:14)
      at OptionManager.init (node_modules/babel-core/lib/transformation/file/options/option-manager.js:368:12)
      at File.initOptions (node_modules/babel-core/lib/transformation/file/index.js:212:65)
      at new File (node_modules/babel-core/lib/transformation/file/index.js:135:24)
      at Pipeline.transform (node_modules/babel-core/lib/transformation/pipeline.js:46:16)

package.json

{
  "name": "example",
  "version": "1.0.0",
  "private": true,
  "description": "example",
  "main": "build/index.js",
  "scripts": {
    "build": "npm run build:ui && npm run build:api",
    "build:api": "tsc && rsync -a --include '*/' --include '*.txt' --exclude '*' lib/ build/",
    "lint": "tslint 'lib/**/*.ts' && eslint --ext .js,.vue client/src",
    "lint:api": "tslint lib/**/*.ts",
    "pretest": "find build -name '*.integration.*' -delete && ./scripts/check_nodejs_version.sh && tsc",
    "start": "node build/index.js",
    "test": "NODE_ENV=test nyc mocha",
    "serve:ui": "vue-cli-service serve client/src/main.js",
    "build:ui": "vue-cli-service build --dest build/public/ client/src/main.js",
    "lint:ui": "vue-cli-service lint",
    "test:unit:ui": "vue-cli-service test:unit"
  },
  "dependencies": {
    "@types/bcrypt": "^1.0.0",
    "@types/bunyan": "^1.8.4",
    "@types/config": "0.0.33",
    "@types/handlebars": "^4.0.38",
    "@types/ioredis": "^3.2.11",
    "@types/koa": "^2.0.46",
    "@types/koa-bodyparser": "^3.0.20",
    "@types/koa-router": "^7.0.30",
    "@types/koa-send": "^4.1.0",
    "@types/node": "^8.10.25",
    "@types/nodemailer": "^4.6.2",
    "aws-sdk": "^2.268.1",
    "axios": "^0.17.1",
    "bcrypt": "^1.0.3",
    "bluebird": "^3.5.1",
    "bull": "^3.4.7",
    "bunyan": "^1.8.12",
    "bunyan-syslog": "git+ssh://git@github.com/jdubjdub/node-bunyan-syslog.git",
    "config": "^1.30.0",
    "d3": "^4.12.0",
    "font-awesome-webpack": "^0.0.5-beta.2",
    "handlebars": "^4.0.11",
    "ioredis": "^3.2.2",
    "jquery": "^3.2.1",
    "koa": "^2.0.0",
    "koa-bodyparser": "^3.1.0",
    "koa-router": "^7.0.1",
    "koa-send": "^4.1.2",
    "materialize-css": "^0.100.2",
    "md5": "^2.2.1",
    "mjml": "^4.1.0",
    "moment": "^2.22.2",
    "nodemailer": "^4.6.7",
    "otplib": "^10.0.1",
    "pg-promise": "^7.3.1",
    "vue": "^2.5.12",
    "vue-resource": "^1.3.5",
    "vue-router": "^3.0.1",
    "vue2-ace-editor": "0.0.3",
    "webpack": "^4.20.2"
  },
  "devDependencies": {
    "@babel/core": "^7.1.2",
    "@babel/preset-env": "^7.1.0",
    "@types/bluebird": "^3.5.21",
    "@types/bull": "^3.3.19",
    "@types/chai": "^4.1.4",
    "@types/mjml": "^4.0.0",
    "@types/mocha": "^2.2.33",
    "@types/uuid": "^3.4.3",
    "@vue/cli-plugin-babel": "^3.0.4",
    "@vue/cli-plugin-eslint": "^3.0.4",
    "@vue/cli-plugin-unit-jest": "^3.0.4",
    "@vue/cli-service": "^3.0.4",
    "@vue/eslint-config-standard": "^3.0.4",
    "@vue/test-utils": "^1.0.0-beta.20",
    "autoprefixer": "^7.2.3",
    "babel-eslint": "^8.2.5",
    "babel-jest": "^23.6.0",
    "babel-loader": "^7.1.5",
    "babel-plugin-istanbul": "^4.1.5",
    "babel-plugin-transform-runtime": "^6.23.0",
    "babel-preset-stage-2": "^6.24.1",
    "babel-register": "^6.26.0",
    "chai": "^4.2.0",
    "cross-env": "^5.2.0",
    "cross-spawn": "^5.1.0",
    "css-loader": "^0.28.7",
    "eslint": "^4.13.1",
    "eslint-friendly-formatter": "^3.0.0",
    "eslint-loader": "^1.9.0",
    "eslint-plugin-html": "^4.0.5",
    "inject-loader": "^3.0.1",
    "karma": "^3.0.0",
    "karma-coverage": "^1.1.1",
    "karma-mocha": "^1.3.0",
    "karma-phantomjs-launcher": "^1.0.2",
    "karma-phantomjs-shim": "^1.4.0",
    "karma-sinon-chai": "^1.3.1",
    "karma-sourcemap-loader": "^0.3.7",
    "karma-spec-reporter": "0.0.31",
    "karma-webpack": "^2.0.2",
    "madge": "^3.2.0",
    "mocha": "^4.0.1",
    "mocha-typescript": "^1.1.16",
    "nightwatch": "^1.0.6",
    "node-notifier": "^5.1.2",
    "nyc": "^13.0.0",
    "optimize-css-assets-webpack-plugin": "^3.2.0",
    "ora": "^1.2.0",
    "phantomjs-prebuilt": "^2.1.14",
    "portfinder": "^1.0.13",
    "postcss-import": "^11.0.0",
    "postcss-loader": "^2.0.9",
    "rimraf": "^2.6.2",
    "selenium-server": "^3.13.0",
    "semver": "^5.4.1",
    "shelljs": "^0.7.8",
    "sinon": "^4.0.0",
    "sinon-chai": "^2.8.0",
    "source-map-support": "*",
    "ts-node": "^3.3.0",
    "tslint": "^5.10.0",
    "typescript": "^2.9.2",
    "uglifyjs-webpack-plugin": "^1.2.7",
    "uuid": "^3.3.2",
    "vue-loader": "^15.4.2",
    "vue-style-loader": "^3.0.3",
    "vue-template-compiler": "^2.5.12",
    "webpack-bundle-analyzer": "^2.13.1",
    "webpack-dev-server": "^3.1.9",
    "webpack-merge": "^4.1.3"
  },
  "nyc": {
    "check-coverage": true,
    "lines": 0,
    "statements": 0,
    "functions": 0,
    "branches": 0,
    "include": [
      "build/api/**/*.js"
    ],
    "exclude": [
      "test/**/*.js"
    ],
    "reporter": [
      "lcov",
      "text-summary"
    ],
    "all": true
  },
  "engines": {
    "node": ">= 8.11.0",
    "npm": ">= 5.6.0"
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not ie <= 8"
  ],
  "postcss": {
    "plugins": {
      "autoprefixer": {}
    }
  },
  "jest": {
    "moduleFileExtensions": [
      "js",
      "jsx",
      "json",
      "vue"
    ],
    "transform": {
      "^.+\\.vue$": "vue-jest",
      "^.+\\.js$": "babel-jest",
      "^.+\\.jsx?$": "babel-jest",
      ".+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$": "jest-transform-stub"
    },
    "moduleNameMapper": {
      "^@/(.*)$": "<rootDir>/src/$1"
    },
    "snapshotSerializers": [
      "jest-serializer-vue"
    ],
    "testMatch": [
      "**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)"
    ],
    "testURL": "http://localhost/"
  },
  "babel": {
    "presets": [
      "@babel/preset-env",
      [
        "@vue/app",
        {
          "useBuiltIns": "entry"
        }
      ]
    ]
  }
}

I wiped the node_modules and npm cache before attempting.

adamchenwei commented 5 years ago

preset-env

What does that mean? How that relate to Vuejs problem we are having?

Akryum commented 5 years ago

Please see how to clear jest cache.

Bowens20832 commented 5 years ago

@Akryum I can confirm this is still an issue. I cleared the Jest cache like you said and I am still getting the "SyntaxError: Unexpected token import" error.

I am on Windows 10.

waghcwb commented 5 years ago

I can confirm the bug on Windows 10 too.

Bowens20832 commented 5 years ago

Alright, Windows was not the issue. I was able to get Jest running with Vue CLI 3 again with the steps below:

Create .env.test in your project root.

Add these two variables to the file:

VUE_CLI_BABEL_TARGET_NODE=true
VUE_CLI_BABEL_TRANSPILE_MODULES=true

Save and run Jest from the CLI GUI and it should work.

ghost commented 5 years ago

I tried all of the above, but it not work environment mac:10.13.6 node: v8.12.0 npm: 6.4.1 vue: 3.0.5

jewbetcha commented 5 years ago

I'm experiencing this as well. Linux 16.04 Node 10.x vue-cli 3.x

Tried everything, no luck :( I just want to write tests

onekiloparsec commented 5 years ago

I must say I am a bit puzzled by the duration of that issue, and the absence of even a hint on the solution we could build to solve it.

scambier commented 5 years ago

For what it's worth, in my case this problem is caused by ts-jest, since version 23.10.3. Version 23.10.2 works correctly.

Edit: fixed it by replacing the contents of my jest.config.js with

module.exports = {
  preset: 'ts-jest'
}

Versions:

"@types/jest": "^23.3.9",
"jest": "^23.6.0",
"ts-jest": "^23.10.4",
adamchenwei commented 5 years ago

the only way I resolved it is by NOT to use vue-cli but use its babel plugin.. (ironically). whoever'd like to temporarily unjam themselve, feel free to take a look! https://github.com/adamchenwei/vuejs-storybook-storyshot-jest-webpack-boilerplate

komali2 commented 5 years ago

Please see how to clear jest cache.

I ran node node_modules/jest/bin/jest.js --clearCache

Did not work.

So, I did it again, then rm -rf node_modules, cleared npm cache, npm installed, then ran the jest cache clear again, then tried testing again, did not work.

komali2 commented 5 years ago

VUE_CLI_BABEL_TARGET_NODE=true VUE_CLI_BABEL_TRANSPILE_MODULES=true

I did

.env.test

VUE_CLI_BABEL_TARGET_NODE=true
VUE_CLI_BABEL_TRANSPILE_MODULES=true

This did not solve the issue.

komali2 commented 5 years ago

For what it's worth, in my case this problem is caused by ts-jest, since version 23.10.3. Version 23.10.2 works correctly.

Edit: fixed it by replacing the contents of my jest.config.js with

module.exports = {
  preset: 'ts-jest'
}

Versions:

"@types/jest": "^23.3.9",
"jest": "^23.6.0",
"ts-jest": "^23.10.4",

"plugin ts-jest not found"

Solution did not work

adamchenwei commented 5 years ago

@komali2 its something wrong with babel and NODE_ENV

komali2 commented 5 years ago

I've solved the issue.

Make sure you have these exact versions of the following packages installed:

  "devDependencies": {
    "@vue/cli-plugin-babel": "^3.0.5",
    "@vue/cli-plugin-eslint": "^3.0.5",
    "@vue/cli-plugin-unit-jest": "^3.0.5",
    "@vue/cli-service": "^3.0.5",
    "@vue/test-utils": "^1.0.0-beta.20",
    "babel-core": "7.0.0-bridge.0",
    "babel-jest": "^23.0.1",
    "vue-template-compiler": "^2.5.17"
  },
  "dependencies": {
    "vue": "^2.5.17"
  },

Only with this exact combination were we able to get jest tests to work.

komali2 commented 5 years ago

@jewbetcha what's confusing? What more information can I give you? What error are you getting with the above?

caroguerrero commented 5 years ago

It's works for me with this line:

transform: {
'^.+\\.(js|jsx)?$': '<rootDir>/node_modules/babel-jest'
}

I don't like this solution. Any idea why jest does not find babel-jest?

jewbetcha commented 5 years ago

@komali2 nothing confusing, it's just tough to jump around versions with a pre-existing project. I'm not sure I'll be able to try that solution or not

komali2 commented 5 years ago

@jewbetcha why won't you be able to try it? Just try it lol

onekiloparsec commented 5 years ago

Lol, I think I tried every solution proposed here. None worked, even @komali2 's

d-ryabtsev commented 5 years ago

None of these solutions worked for me.. getting the same issue

takahser commented 5 years ago

same here, tried everything, still won't work

fs-jonathan commented 5 years ago

I have encountered the same problem.

After trying all the solutions above, I tried to update all the package to the latest version. And then for some search results that I execute 'yarn', in reason unknown that I have solved the problem. I have never installed anything with 'yarn' but just using 'npm' or 'vue ui' before. Reference: https://github.com/vuejs/vue-cli/issues/1189

It would be great if anyone can tell me the reason.

This part added in package.json

  "babel": { // This setting will help solving the library import issue
    "presets": [
      "@babel/preset-env",
      [
        "@vue/app",
        {
          "useBuiltIns": "entry"
        }
      ]
    ]
  },

jest.config.js

module.exports = {
  moduleFileExtensions: [
    'js',
    'jsx',
    'json',
    'vue'
  ],
  transform: {
    '^.+.js$': 'babel-jest',
    '.*.(vue)$': 'vue-jest', // This part will help to solve the issue of transforming <template> etc. in vue code into proper format for testing
    '.+\\.(css|styl|less|sass|scss|png|jpg|svg|ttf|woff|woff2)$': 'jest-transform-stub',
  },
  transformIgnorePatterns: [
    "node_modules/(?!jest-test)"
  ],
  moduleNameMapper: {
    '^@/(.*)$': '<rootDir>/src/$1'
  },
  snapshotSerializers: [
    'jest-serializer-vue'
  ],
  testMatch: [
    '**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)'
  ],
  testURL: 'http://localhost/'
}

The other parts are almost the same as of what vue-cli provided by default.

Update after restart the Mac: Suddenly it didn't work again after a long break at the end of the day.
Finally it somehow resolved by doing every kind of cache clearing process and updating the command in package.json as "test:unit": "jest --clearCache && vue-cli-service test:unit --watchAll". Then the test can be run successfully on the second time.

sgashler commented 5 years ago

I tried many of the above solutions to no avail. In the end, running jest --clearCache finally solved the problem for me. The actual fix could have been any combination of the above solutions but I didn't realize it until clearing jest's cache. I thought that running rm -rf node_modules and npm install, which I also tried many times, would effectively clear jest's cache, but apparently not.

mariacheline commented 5 years ago

Wow, this has been going on.. is there still no stable solution?

LinusBorg commented 5 years ago

Well it's pretty hard to pin down, unfortunately. I for example simply can't reproduce it here on my machine.

It seems to be related to the environment variables we use as flags to re-configure the babel app preset when running jest vs. when running webpack, but as to why or how this happens, I personally have no idea.

I also think that besides that core issue, we have a lot of other small issues in this thread that could be solved by emptying a cache or updating dependencies, which explains all of the different solutions that only work for some people and not for others.

I'm thankful for people's patience, and can assure you we are still looking into this, but as I said, it's hard to pin down what the cause is really supposed to be.

IT would be really helpful if people tried to come up with reproductions, really. The only reproduction code shared with us so far is the one from OP, which was built with 3.0.0-rc.2 and is therefore hardly applicable to the current state of things.

"Same problem here" certainly doesn't help us fix is.

onekiloparsec commented 5 years ago

Thanks @LinusBorg for letting us know you're still aware of the issue.

I am not 100% sure that adding one more thing is useful, but I just tried and succeeded to workaround the problem on my side, after having tried everything that is proposed in this thread. I tend to think the workaround indicates there are different problems involved in this thread, and thus should be closed, while new issues must be reopened for each individual problem.

So, here it is. The error message I had is exactly what has been invoked in the first place, that is an SyntaxError: Unexpected token import. Here is the message (it comes from a test of a Login component, with 2 input fields and a login button).

  ● Test suite failed to run

    Jest encountered an unexpected token

    This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.

    By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".

    Here's what you can do:
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/en/configuration.html

    Details:

    /Users/onekiloparsec/code/arcsecond-front/node_modules/vue-skycons/index.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import Skycons from './skycons';
                                                                                             ^^^^^^

    SyntaxError: Unexpected token import

      28 | 
      29 | import LabelCentered from '@/components/labels/LabelCentered'
    > 30 | import LabelError from '@/components/labels/LabelError'
         |                                          ^
      31 | 
      32 | import skyUtils from './mixins/skyUtils'
      33 | import dateUtils from './mixins/dateUtils'

      at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:403:17)
      at Object.<anonymous> (src/main.js:30:42)
      at Object.<anonymous> (src/store/modules/auth.js:18:13)

Two things I note here: 1) the failing import has nothing to do with the test itself, and 2) the error "cursor" (at line 30) seems unrelated to the error itself too. So very strange. If I comment the import of Skycons, it fails the same way on another similar import line.

At that point, I noticed that importing Skycons is totally silly for running my tests. My feeling was that my tests setup was importing way too many and unnecessary things.

There were 2 difficulties in my tests: mixins and a Vuex store. In particular, the Vuex store was importing one of the actualy vuex module/namespace: auth (see the last line of error message).

I worked around the test error by stubbing entirely the auth vuex module.

Here is my test (LabelError is a custom component used to display an error message): Login.spec.js:

import Vuex from 'vuex'
import { createLocalVue, RouterLinkStub, shallowMount } from '@vue/test-utils'

import assetsSourcePaths from '@/mixins/assetsSourcePaths'
import Login from '@/pages/accounts/Login.vue'

const localVue = createLocalVue()
localVue.use(Vuex)

describe('Login.vue', () => {
  let auth = { namespaced: true }
  let store
  let wrapper

  beforeEach(() => {
    auth.actions = {
      loginUser: jest.fn()
    }

    store = new Vuex.Store({
      modules: {
        auth
      },
      strict: true
    })

    wrapper = shallowMount(Login, {
      localVue,
      store,
      stubs: {
        RouterLink: RouterLinkStub,
        LabelError: true
      },
      mixins: [
        assetsSourcePaths
      ]
    })
  })

  it('has a title', () => {
    expect(wrapper.find('h2').text()).toMatch('Log In')
  })

  it('has valid default data', () => {
    expect(wrapper.vm.isLoggingIn).toBe(false)
    expect(wrapper.vm.loginError).toBe(null)
  })

  it('has two inputs', () => {
    const inputArray = wrapper.findAll('input')

    expect(inputArray.at(0).element.value).toMatch('')
    expect(inputArray.at(1).element.value).toMatch('')

    expect(inputArray.at(0).attributes().name).toMatch('username')
    expect(inputArray.at(1).attributes().name).toMatch('password')

    expect(inputArray.at(0).attributes().type).toMatch('text')
    expect(inputArray.at(1).attributes().type).toMatch('password')

    expect(inputArray.at(0).attributes().disabled).toBeUndefined()
    expect(inputArray.at(1).attributes().disabled).toBeUndefined()

    expect(inputArray.at(0).contains('p.text-danger')).toBe(false)
    expect(inputArray.at(1).contains('p.text-danger')).toBe(false)
  })

  it('has a button', () => {
    expect(wrapper.contains('button')).toBe(true)
    expect(wrapper.find('button').attributes().name).toBe('submit')
    expect(wrapper.find('button').attributes().disabled).toBeDefined()
  })

  it('should trigger login when button is clicked', (done) => {
    const credentials = { username: 'john', password: 'doe' }
    wrapper.setData({ credentials: credentials })

    const button = wrapper.find('button')
    button.trigger('click')
    expect(auth.actions.loginUser).toHaveBeenCalled()
    expect(auth.actions.loginUser.mock.calls[0][1]).toEqual(credentials)

    expect(button.attributes().disabled).toBeDefined()

    expect(wrapper.vm.isLoggingIn).toBe(true)
    expect(wrapper.vm.loginError).toBe(null)

    const inputArray = wrapper.findAll('input')
    expect(inputArray.at(0).attributes().disabled).toBeDefined()
    expect(inputArray.at(1).attributes().disabled).toBeDefined()

    wrapper.vm.$nextTick(() => {
      expect(wrapper.vm.isLoggingIn).toBe(false)
      expect(wrapper.vm.loginError).toBe(null)
      done()
    })
  })
})

And here are my configs: babel.config.js:

module.exports = {
  presets: [
    '@vue/app'
  ]
}

And jest.config.js:

module.exports = {
  moduleFileExtensions: [
    'js',
    'jsx',
    'json',
    'vue'
  ],
  transform: {
    '^.+\\.vue$': 'vue-jest',
    '.+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub',
    '^.+\\.jsx?$': 'babel-jest'
  },
  moduleNameMapper: {
    '^@/(.*)$': '<rootDir>/src/$1'
  },
  snapshotSerializers: [
    'jest-serializer-vue'
  ],
  testMatch: [
    '**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)'
  ],
  transformIgnorePatterns: [
    '<rootDir>/node_modules/',
    '<rootDir>/dist/'
  ],
  testURL: 'http://localhost/',
  setupFiles: [
    'jest-localstorage-mock'
  ]
}

Vue version: 3.0.5 (I started to note the problems since -RC3).

chriszrc commented 5 years ago

For me this problem only showed up when the tests involved imported vue components (in this case from bootstrap-vue) that were exported as pure es6.

A combination of the fixes above solved this, I had to:

  1. Add the babel-jest transform (as the last entry in transform section of jest.config.js)

    '^.+\\.js$': 'babel-jest',
  2. Add transformIgnorePatterns with a pattern specifically excluding bootstrap-vue

    transformIgnorePatterns: ['<rootDir>/node_modules/(?!bootstrap-vue)']
paulvanbladel commented 5 years ago

This issue drives me crazy. I can get a vue-cli based project working now, by copying it to another drive on my win10 machine. So, the original (non working) is on the d drive. When I copy the sources (except node_modules folder) to the E drive, do there an npm install, all tests work just fine. On the other hand, when I delete in the source folder on the d drive, the node_modules folder, do an npm install, the tests still fail. One would expect that after a delete of npm folder on drive d, the situation on both d and f drive are the same, but it's not :(

buffet-time commented 5 years ago

Also having this issue ;/ https://stackoverflow.com/questions/53397773/node-modules-not-being-parsed-correctly-for-tests

nueBuild commented 5 years ago

I was having this issue too. This is how I got the tests working again.

I had to install the version 7.0.0-bridge.0 for babel-core. "babel-core": "7.0.0-bridge.0"

There is a message in the bable-jest repo about this.

Note: If you are using babel version 7 you have to install babel-jest with

yarn add --dev babel-jest 'babel-core@^7.0.0-bridge' @babel/core

and the Vue cli-plugin-babel is installing @bable/core ^7.0.0

I hope this helps anyone still having this issue.

chriszrc commented 5 years ago

Interesting. The lastest version of the vue cli is actually already setup to include this dependency, here's what I'm seeing in my package.json:

"babel-core": "7.0.0-bridge.0",

Obviously for me, just having that didn't solve my problem. Only this did it for me:

https://github.com/vuejs/vue-cli/issues/1584#issuecomment-439718686

paulvanbladel commented 5 years ago

@LinusBorg If you need an additional repo for reproducing: https://github.com/paulvanbladel/quasar-jest/tree/master/quasar-with-vue-cli It's a quasar app, but generated with the vue-cli 3. Cheers.

LinusBorg commented 5 years ago

Thanks.

bennettdams commented 5 years ago

I encountered a weird side effect: Running all tests (npm run test:unit) works without problems, running one specific test (npm run test:unit -t App for App.spec.js) fails.

The script: "test:unit": "vue-cli-service test:unit --no-cache"

    Details:

    SyntaxError: [BABEL] unknown: Unexpected token m in JSON at position 0 (While processing: "C:\\Coding\\...\\node_modules\\@vue\\babel-preset-app\\index.js$2")
        at JSON.parse (<anonymous>)

      at Object.parseSourceMapInput (node_modules/jest-runner/node_modules/source-map/lib/util.js:433:15)
          at Array.map (<anonymous>)
      at extendedTrace (node_modules/@babel/template/lib/builder.js:70:15)
      at Object.assign.args (node_modules/@babel/template/lib/builder.js:27:14)
      at exports.default (node_modules/babel-plugin-dynamic-import-node/lib/index.js:13:21)
      at loadDescriptor (node_modules/@babel/core/lib/config/full.js:165:14)
      at cachedFunction (node_modules/@babel/core/lib/config/caching.js:33:19)
      at loadPluginDescriptor (node_modules/@babel/core/lib/config/full.js:200:28)
      at config.plugins.reduce (node_modules/@babel/core/lib/config/full.js:69:20)
          at Array.reduce (<anonymous>)

package.json

"devDependencies": {
"@vue/cli-plugin-babel": "^3.1.1",
"@vue/cli-plugin-unit-jest": "^3.1.1",
"@vue/cli-service": "^3.1.4",
"@vue/test-utils": "^1.0.0-beta.20",
"babel-core": "7.0.0-bridge.0",
"babel-jest": "^23.0.1",
...
}

babel.config.js

module.exports = {
presets: ["@vue/app"]
};

jest.config.js

module.exports = {
moduleFileExtensions: ["js", "jsx", "json", "vue"],
verbose: true,
transform: {
"^.+\\.vue$": "vue-jest",
".+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$":
"jest-transform-stub",
"^.+\\.jsx?$": "babel-jest",
"^.+\\.js$": "babel-jest"
},
moduleNameMapper: {
"^@/(.*)$": "<rootDir>/src/$1",
"^tests/(.*)$": "<rootDir>/tests/$1"
},
snapshotSerializers: ["jest-serializer-vue"],
testMatch: [
"**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)"
],
testURL: "http://localhost/"
};
mvrska commented 5 years ago

if anyone trying to use the nuxt.js/examples/jest-vtu-example/ is having this issue, mine was failing on the transform config.

in nuxt.js/examples/jest-vtu-example/ the package.json has "^.+\\.js$": "<rootDir>/node_modules/babel-jest",

Adding parentheses around the file extension solved it for me "^.+\\.(js)$": "<rootDir>/node_modules/babel-jest",

complete package.json

{
  "scripts": {
    "dev": "nuxt",
    "build": "nuxt build",
    "start": "nuxt start",
    "generate": "nuxt generate",
    "test": "jest ."
  },
  "dependencies": {
    "nuxt": "latest",
    "@nuxtjs/auth": "^4.5.3",
    "@nuxtjs/axios": "^5.3.6",
    "cross-env": "^5.2.0",
    "element-theme-chalk": "^2.4.9",
    "element-ui": "^2.4.6",
    "normalize.css": "^8.0.1",
    "nuxt-i18n": "^5.4.4"
  },
  "devDependencies": {
    "@babel/core": "^7.1.6",
    "@vue/test-utils": "^1.0.0-beta.25",
    "babel-core": "^7.0.0-bridge.0",
    "babel-eslint": "^10.0.1",
    "babel-jest": "^23.6.0",
    "element-theme": "^2.0.1",
    "eslint": "^5.9.0",
    "eslint-loader": "^2.0.0",
    "eslint-plugin-vue": "^4.0.0",
    "jest": "^23.6.0",
    "jest-puppeteer": "^3.5.1",
    "jest-serializer-vue": "^2.0.2",
    "node-sass": "^4.10.0",
    "nodemon": "^1.18.6",
    "nuxt-sass-resources-loader": "^2.0.5",
    "puppeteer": "^1.10.0",
    "sass-loader": "^7.1.0",
    "vue-jest": "^3.0.0"
  },
  "jest": {
    "moduleFileExtensions": [
      "js",
      "json",
      "vue"
    ],
    "watchman": false,
    "moduleNameMapper": {
      "^~/(.*)$": "<rootDir>/$1",
      "^~~/(.*)$": "<rootDir>/$1"
    },
    "transform": {
      "^.+\\.(js)$": "<rootDir>/node_modules/babel-jest",
      ".*\\.(vue)$": "<rootDir>/node_modules/vue-jest"
    },
    "snapshotSerializers": [
      "<rootDir>/node_modules/jest-serializer-vue"
    ],
    "collectCoverage": true,
    "collectCoverageFrom": [
      "<rootDir>/components/**/*.vue",
      "<rootDir>/pages/*.vue"
    ]
  }
}
paulvanbladel commented 5 years ago

@mvrska thx, but on https://github.com/paulvanbladel/quasar-jest/tree/master/quasar-with-vue-cli, it has not effect :(

esappear commented 5 years ago

Check your babel-core version. I fix it by declare babel-core version to ^7.0.0-0" in package.json. If not, installing babel-jest also brings you babel-core in version 6.26.3.

"devDependencies": {
    "@vue/cli-plugin-babel": "^3.0.1",
    "@vue/cli-plugin-eslint": "^3.0.1",
    "@vue/cli-service": "^3.0.1",
    "@vue/cli-plugin-unit-jest": "^3.0.1",
    "babel-eslint": "^10.0.1",
    "babel-jest": "^23.6.0",
    "babel-core": "^7.0.0-0",
    "eslint": "^5.8.0",
    "eslint-plugin-vue": "^5.0.0-0",
    "jest": "^23.6.0",
    "vue-jest": "^3.0.0",
    "vue-template-compiler": "^2.5.17"
  }
paulvanbladel commented 5 years ago

@esappear that version of babel-core doens't seem to exist. When I replace "babel-core": "7.0.0-bridge.0", with yours I get an error when running npm install

paulvanbladel commented 5 years ago

@LinusBorg I updated https://github.com/paulvanbladel/quasar-jest/tree/master/quasar-with-vue-cli to the latest vue bits. So please take that version also; I appreciate the effort from everyone involved in this issue, but maybe we should verify the various proposed solutions against the same repo. It is clear the the issue is based on something highly fragile (on bad days, I suspect the whole modern web dev world is highly fragile :) ) So, in order to exclude false positives, please test your proposed solution against the aforementioned repo, so that we can come up with something reproducable. Thanks a lot !

dancon commented 5 years ago

@ijdickinson It seem like a usual mistake when you set your bable.config.js with below config:

 presets: [
    ['@babel/preset-env', { modules: false }]
]

you can not set modules: false when NODE_ENV is test, it make the babel not to transform the import syntax to commonjs, you can modify the babel.config like below to fix it:

const isDev = process.env.NODE_ENV === 'development'
 presets: [
    ['@babel/preset-env', { modules: isDev ? false : 'cjs' }]
]

OR

presets: [
   ['@babel/preset-env', { modules: false }]
],
// ... some other configuration
env: {
   test: {
      presets: [
           ['@babel/preset-env', { modules: 'cjs' }]
      ]
  }
}

NOTE: DONOT export a function in babel.config.js, just export a Object, like this:

module.exports = {
   presets: [ ... ],
   plugins: [ ... ],
   env: {
      test: { ... }
   }
}
chriszrc commented 5 years ago

For those using the cli, the docs indicate that for jest tests, the modules setting is

auto set to 'commonjs' in Jest tests

https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/babel-preset-app

Are you saying that's the right way to do it?