Coverage Report with Jest and Vue not working - vue.js

I am unit testing my Vue project with Jest and I get the code coverage in the console, no problems there, however the HTML report is not working -
package.json:
...
"unit": "jest --config test/unit/jest.conf.js --coverage",
...
jest.conf.js:
const path = require('path')
module.exports = {
verbose: true,
testURL: "http://localhost/",
rootDir: path.resolve(__dirname, '../../'),
moduleFileExtensions: [
'js',
'json',
'vue'
],
moduleNameMapper: {
'^#/(.*)$': '<rootDir>/src/$1'
},
transform: {
'^.+\\.js$': '<rootDir>/node_modules/babel-jest',
'.*\\.(vue)$': '<rootDir>/node_modules/vue-jest'
},
testPathIgnorePatterns: [
'<rootDir>/test/e2e'
],
snapshotSerializers: ['<rootDir>/node_modules/jest-serializer-vue'],
setupFiles: ['<rootDir>/test/unit/setup'],
mapCoverage: true,
coverageDirectory: '<rootDir>/test/unit/coverage',
collectCoverageFrom: [
'src/**/*.{js,vue}',
'!src/main.js',
'!src/router/index.js',
'!src/plugins/vuetify.js',
'!**/node_modules/**'
]
}
What might be the cause of that? Thank you in advance.

It looks like your coverage report property might need to be adjusted. You should try including html in your coverageReporters, like this:
module.exports = {
...
coverageReporters: ['html']
...
}

Related

moduleNameMapper in jest.config.cjs is not working?

File Structure:
public
- assets
src
other file
Svelte.config.js
resolve: {
alias: {
"#": resolve(__dirname, "src"),
$assets: resolve(__dirname, "public/assets"),
},
},
Jest.config.cjs
const sveltePreprocess = require("svelte-preprocess");
module.exports = {
transform: {
"^.+\\.svelte$": ["svelte-jester", [sveltePreprocess()]],
"^.+\\.js$": "babel-jest",
"^.+\\.(png|svg)$": "<rootDir>/svgTransform.js",
},
moduleFileExtensions: ["js", "svelte"],
bail: false,
verbose: true,
testPathIgnorePatterns: ["node_modules"],
transformIgnorePatterns: ["node_modules"],
moduleDirectories: ["node_modules"],
setupFilesAfterEnv: ["#testing-library/jest-dom/extend-expect"],
moduleNameMapper: {
"#/(.*)$": "<rootDir>/src/$1",
"$assets/(.*)$": "<rootDir>/public/assets/$1",
},
setupFiles: ["<rootDir>/setupTests.js"],
testResultsProcessor: "jest-sonar-reporter",
testTimeout: 30000,
testEnvironment: "jsdom",
};
Usage:
import SvgClose from "$assets/svg/close.svg";
Error:
Cannot find module '$assets/svg/close.svg' from 'src/components/atoms/Modal.svelte'
# work fine but $assets not working .
What changes I should do in jest.config.cjs
or I am Missing something?

Vue 3 vendor bundle is bloated with #babel/parser/lib when vue.esm-bundler.js is used in webpack

I created a Vue 3 project and using webpack for bundling the package. Since I have in-DOM templates, I cannot go with the default #runtime-dom. So I have aliased Vue to point to vue.esm-bundler.js.
The issue I am facing is that, when I take a prod build, my vendor bundle is bloated with #babel/parser/lib.
Sample project to reproduce this issue is available here
Steps to follow:
npm install
npm run bundle
Open dist folder and see the Webpack bundle analyser report.
For ease of config, pasting the configs below.
webpack.config.js
const path = require("path");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer")
.BundleAnalyzerPlugin;
const { VueLoaderPlugin } = require("vue-loader");
const TerserPlugin = require("terser-webpack-plugin");
module.exports = (env, options) => {
const devMode = options.mode != "production";
return {
context: path.resolve(__dirname, "src"),
entry: {
"vue-bundle": "./entry/main.js",
},
output: {
path: path.resolve(__dirname, "dist"),
filename: "[name].js",
chunkFilename: "[name].js",
},
module: {
rules: [
{
test: /\.js$/,
exclude: [/node_modules/],
use: {
loader: "babel-loader",
options: {
presets: [
[
"#babel/preset-env",
{
targets: [">25%"],
debug: true,
corejs: "3.6.5",
useBuiltIns: false,
},
],
],
},
},
},
{
test: /\.vue$/,
use: "vue-loader",
},
],
},
plugins: [
new CleanWebpackPlugin(),
new VueLoaderPlugin(),
new BundleAnalyzerPlugin({
openAnalyzer: false,
analyzerMode: "static",
reportFilename: "webpack_bundle_analyser_report.html",
defaultSizes: "gzip",
}),
],
optimization: {
mangleWasmImports: true,
removeAvailableModules: true,
sideEffects: true,
minimize: devMode ? false : true,
minimizer: [
new TerserPlugin({
test: /\.js(\?.*)?$/i,
exclude: /\/node-modules/,
parallel: 4,
extractComments: false,
}),
],
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: "vendor-bundle",
chunks: "all",
},
},
},
},
devtool: devMode ? "eval-cheap-source-map" : false,
resolve: {
extensions: [".ts", ".js", ".vue", ".json"],
alias: {
vue: "vue/dist/vue.esm-bundler.js"
},
},
};
};
package.json
{
"name": "testPro",
"version": "1.0.0",
"private": true,
"scripts": {
"bundle": "webpack --mode=production --config webpack.config.js",
"bundle-dev": "webpack --mode=development --config webpack.config.js"
},
"devDependencies": {
"#babel/core": "^7.12.3",
"#babel/preset-env": "^7.12.1",
"#babel/preset-typescript": "^7.12.1",
"#vue/compiler-sfc": "^3.0.2",
"babel-loader": "^8.1.0",
"clean-webpack-plugin": "^3.0.0",
"core-js": "^3.6.5",
"regenerator-runtime": "^0.13.7",
"terser-webpack-plugin": "^5.0.3",
"vue-loader": "^16.0.0-beta.4",
"webpack": "^5.3.0",
"webpack-bundle-analyzer": "^3.9.0",
"webpack-cli": "^4.1.0"
},
"dependencies": {
"vue": "^3.0.2"
}
}
Entry file main.js
import { createApp } from 'vue';
import App from '../App.vue';
createApp(App).mount('#app');
Not able to get what I am missing.
I strongly believe it is a bug in Vue 3 so I submitted a bug report - you can track it here
...I reproduced it myself using Vue CLI just to eliminate the chance the problem is in your Webpack config
You have 2 options to workaround this issue:
If you don't need to release right now, just work on your project and wait for a fix (I'm pretty sure it will be fixed - Vue builds for a browser which include compiler does not depend on #babel/parser so it's clear Vue don't need it to work correctly inside browser)
Don't use in-DOM templates and template option (string templates) - put everything in .vue files, <template></template> blocks - Runtime + Compiler vs. Runtime-only. Then you don't need a build with compiler...
EDIT: removed the part about missing process.env.NODE_ENV as --mode param to Webpack CLI does exactly that...

(JEST/VueJS) Cannot use import statement outside a module

I'm using windows10 and when I run Jest on VUEJS project for tests i've got this :
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import { shallowMount } from '#vue/test-utils';
^^^^^^
SyntaxError: Cannot use import statement outside a module
at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1086:14)
Itried a lot of soltions, but still not working Here is my jest.config.js file:
module.exports = {
moduleFileExtensions: ['js', 'jsx', 'json', 'vue'],
transform: {
"^.+\\.js$": "babel-jest",
".+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$": "jest-transform-stub"
},
moduleNameMapper: {
"^.+.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$": "jest-transform-stub"
},
snapshotSerializers: [
"<rootDir>/node_modules/jest-serializer-vue"
],
testMatch: [
'<rootDir>/tests/**/*.spec.(js|jsx|ts|tsx)|<rootDir>/**/__tests__/*.(js|jsx|ts|tsx)'
],
transformIgnorePatterns: ['<rootDir>/node_modules/']
};

ElementUI tests throw ReferenceError: _Message is not defined

Bug report on ElementUI
I am using On-demand loading of ElementUI components. I've followed the instructions correctly and it works just fine when running the app.
The problem arises when I try to test with Jest and Vue test utils. None of the components I am importing seem to be found, so I get this error when running my tests:
ReferenceError: _Message is not defined
I get the same error for any of the other components, that my test touches.
On the bug report I mentioned above, I am being suggested that my babel configuration is not being applied in my testing environment? Or its something about my Jest configuration. I've tried various things to fix this:
Doing a manual mocks
Spying on the component
Importing the whole ElementUI package inside my test
Updating Jest configuration
Nothing seems to work and I have no idea what is wrong...
bebel.config.js
module.exports = {
presets: [
'#vue/app',
],
plugins: [
[
'component',
{
libraryName: 'element-ui',
styleLibraryName: 'theme-chalk',
},
],
],
};
jest.config.js
module.exports = {
// roots: ['<rootDir>/src/', '<rootDir>/tests/'],
moduleFileExtensions: [
'js',
'jsx',
'json',
'vue',
],
transform: {
'^.+\\.vue$': 'vue-jest',
'.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub',
'^.+\\.jsx?$': 'babel-jest',
},
transformIgnorePatterns: [
'/node_modules/(?!element-ui)',
],
moduleNameMapper: {
'^#/(.*)$': '<rootDir>/src/$1',
'^.+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub',
},
snapshotSerializers: [
'jest-serializer-vue',
],
testMatch: [
'**/tests/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)',
],
testURL: 'http://localhost/',
watchPlugins: [
'jest-watch-typeahead/filename',
'jest-watch-typeahead/testname',
],
collectCoverage: true,
coverageReporters: ['lcov', 'text-summary'],
};
I have a couple of suggestions for you here:
change this in jest.config.js
module.exports = {
moduleFileExtensions: [
'js',
'jsx',
'json',
'vue',
],
transform: {
'^.+\\.vue$': 'vue-jest',
'.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub',
'^.+\\.(js|jsx)?$': 'babel-jest'
},
moduleNameMapper: {
'^#/(.*)$': '<rootDir>/src/$1',
'^.+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub',
},
snapshotSerializers: [
'jest-serializer-vue',
],
testMatch: [
'**/tests/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)',
],
testURL: 'http://localhost/',
watchPlugins: [
'jest-watch-typeahead/filename',
'jest-watch-typeahead/testname',
],
collectCoverage: true,
coverageReporters: ['lcov', 'text-summary'],
};
and this in babel.config.js
module.exports = {
presets: [
'#vue/app',
],
plugins: [
[
'component',
{
libraryName: 'element-ui',
styleLibraryName: 'theme-chalk',
},
],
],
"env": { "test": { "plugins": ["transform-es2015-modules-commonjs", "dynamic-import-node"] } }
};
Also I believe #babel/plugin-transform-modules-commonjs is needed in yarn.
Let me know if this works.

Vuejs + Jest : "SyntaxError: Unexpected token <"

I have a Vue file which imports a Vue file from node_modules. This file seems to not be recognize as a vue file when imported and doesn't use vue-jest.
I tried to use an htmlLoader, but doesn't work either.
Here is the error I get :
path/node_modules/vue-loading-spinner/src/components/Jumper.vue:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){<template>
SyntaxError: Unexpected token <
Here is my jest.conf.js :
const path = require('path')
module.exports = {
rootDir: path.resolve(__dirname, '../../'),
moduleFileExtensions: [
'js',
'json',
'vue',
'html'
],
moduleNameMapper: {
'^#/(.*)$': '<rootDir>/src/$1',
"\\.(css|scss)$": "<rootDir>/test/utils/styleTransform.js"
},
transform: {
'^.+\\.js$': '<rootDir>/node_modules/babel-jest',
'.*\\.vue$': '<rootDir>/node_modules/vue-jest',
"^.+\\.html$": "<rootDir>/test/utils/htmlLoader.js"
},
testPathIgnorePatterns: [
"<rootDir>/node_modules/"
],
modulePaths: [
"<rootDir>"
],
setupFiles: ['<rootDir>/test/unit/setup'],
testMatch: [
'<rootDir>/(test/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx))'
],
testURL: 'http://localhost'
}
Thanks for your help.