Cannot import Vue Component in Jest Test - vue.js

Im trying to write my first test in Jest and cannot make my configuration run with a Vue Component.
In my Laravel Project I installed the needed npm packages with following commands:
npm install -—save-dev jest vue-jest jest-serializer-vue
npm install #vue/test-utils
In my package.json i have following configurations:
"scripts": {
...
"test" : "jest"
}
...
"jest": {
"testRegex": "tests/Javascript/.*.spec.js$"
},
My test is in the given Directory "root/tests/Javascript/Mytest.spec.js".
My test looks like this:
import { mount } from '#vue/test-utils';
// If this is removed it works....
import MyVuePage from './../../resources/js/pages/MyVuePage.vue';
describe('Something', () => {
it("Awesome", () => {
expect(1).toBe(1);
});
});
I get following Error:
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.
In the Console there is a little Arrow Pointing on my "i" of "import SeriesVersion from './../../resources/js/pages/MyVuePage.vue';"
I run the test by writing "npm run test" into the console.
Can you tell me what im doing wrong?

Related

How to add a loader in a Vue/Webpack app to support non JS files used in a dependency of a node module

I have a Vue 2 app that uses Webpack, and I am trying to use in it the node module PSD.js, which in itself utilizes CoffeeScript as part of it's dependencies. When I try to compile i get the error:
Module parse failed: Unexpected character '#' (1:0) You may need an appropriate loader to handle this file type,
referring to the the file ./node_modules/coffee-script/lib/coffee-script/register.js that PSD.js installed as part of it's dependencies when I did npm install psd.
Any ideas on how to make this work?
I understand I need to tell the Vue app how to handle .coffee files with a loader, but I have tried installing coffee-loader, coffee, set the vue.config.js to:
module.exports = {
publicPath: "./",
configureWebpack: {
target: "node-webkit",
node: false,
module: {
rules: [
// ...
{
test: /\.coffee$/,
use: [
{
loader: 'coffee-loader'
}
]
}
]
}
},
lintOnSave: false
};
yet still nothing works, I get the same error. I feel it is because I am not using CoffeeScript directly but rather a node module that I AM using, psd.js, is the one using it. That is why I cannot set lang="coffee" in the script tag attribute of my Vue module (I am using vanilla JS to run everything).
thnx in advance
ADDING MORE INFO:
I use a boilerplate framework to setup my app, and it initialises the vue/webpack app for me indirectly.
To reproduce, and even though this system is for Adobe plugins, you do not need the Adobe host app to see the issue, do:
npm install -g bombino
Then in a folder of your choosing run:
bombino
and fill in these params when asked:
? Name of panel? Hello World
? Use your custom templates or bombino defaults? Bombino
What tooling preset should be used? Vue-CLI
? Which Vue-CLI template should be used? bombino-vue-bare (Absolute minimum)
? Host apps to include: After Effects
? Base CEF Port (between 1024 and 65534) 8666
? Run npm install for you? Yes
then cd into Hello-World and run npm run serve. You should see the app is compiled correctly and is running on some port (8080 or higher if taken).
Now go back to the root folder and install psd.js: npm install psd
then go back into Hello-World and run npm run serve again. This time it will fail to compile with the error I started this question with. Even if you go and install coffee-loader by doing npm install --save coffeescript coffee-loader and change the vue.config.js to be like so:
publicPath: "./",
// Thanks Eric Robinson
configureWebpack: {
target: "node-webkit", // Set the target to node-webkit (https://webpack.js.org/configuration/target/)
node: false, // Don't set certain Node globals/modules to empty objects (https://webpack.js.org/configuration/node/),
module: {
rules: [
// ...
{
test: /\.coffee$/,
use: [
{
loader: 'coffee-loader'
}
]
}
]
}
},
lintOnSave: false
};
or if you do vue use coffee - all of these result in the same error: the compiler/packager doesn't know how to handle the .coffee file (used as a dependency by psd.js).
Thnx again to anyone who has info

Cannot configure Jest for WebStorm/IntelliJ

I have installed Jest using npm :
npm i jest --save-dev
At the package level I also have a Jest config file: jest.config.js which is very simple and just contains :
const config = {
verbose: true,
};
module.exports = config;
However if I look at a test that I wrote, the expect() cannot be compiled :
On closer inspection WebStorm/IntelliJ thinks that describe() and it() belong to mocha, and not jest.
How do I point IntelliJ/WebStorm to jest and not to mocha? I can't seem to find anything in the settings.

Import a NPM module with a Nuxt Application in it

I would like to develop an NPM module that the user can import in his project.
The module contain a full administration panel created with Nuxt.
I don't want the user know anything about Nuxt, he just need to run a command like:
myppcommand start
and the application starts a server that is running the administration panel.
So my idea is to develop the NPM module with Nuxt. Generate all the static file inside ./dist folder and then myappcommand start will serve the app from node_modules.
// NPM Package myapp
// nuxt.config.js
export default {
components: [
{
path: '~/components/',
extensions: ['vue']
}
],
buildDir: './.nuxt',
srcDir: './src/',
target: 'static',
ssr: false,
generate: {
dir: './dist/'
}
};
// NPM Package myapp
npx nuxt generate
The command will generate all files in ./dist folder.
// User repo
npm install myapp
This will install myapp inside ./node_modules.
// User repo
cd node_modules/myapp/ && npx nuxt start -c nuxt.config.js
This will start the server and serve the app.
But is this the best way possible? It seems a bit hacky to me, to go inside node_modules, does somebody know a better way?
You could achieve this by declaring that your package has an executable file which starts Nuxt, in the bin property of package.json.
Firstly, create an executable script to start the app:
bin/start.js
#!/usr/bin/env node
// Based on node_modules/.bin/nuxt
global.__NUXT_PATHS__ = (global.__NUXT_PATHS__ || []).concat(__dirname)
require('#nuxt/cli').run(['start'])
.catch((error) => {
require('consola').fatal(error)
process.exit(2)
})
You can verify that this starts the app by running ./bin/start.js (provided you have made the file executable), or node ./bin/start.js.
Then, declare that your package should install this as a script when installed as a dependency:
package.json
{
"bin": {
"myapp": "bin/start.js"
}
}
When your package has been installed with npm install myapp, then node_modules/.bin/myapp will link to node_modules/myapp/bin/start.js and the user will be able to run it with npx myapp.

Bootstrap-vue components not imported when importing an npm package from local

Okay so maybe this has a fairly simple explanation which I don't know how to look up, but here's my conundrum:
if I publish my project (my-navigation) to the npm registry and then npm install it in another project (my-vue-app), it works all great, but!
if I try to npm install my-navigation directly from its folder on my machine into my-vue-app, I start getting runtime errors indicating that I have not correctly registered some bootstrap-vue components
I have even tried copying the files under node_modules/my-navigation into a folder and then npm installing that - I get the same errors
This is my main entrypoint:
import Vue from "vue";
import MyNavigation from "./MyNav.vue";
import {
BNavbar,
BNavbarBrand,
BNavbarNav,
BDropdownForm
} from "bootstrap-vue";
Vue.component("b-navbar", BNavbar);
Vue.component("b-navbar-brand", BNavbarBrand);
Vue.component("b-navbar-nav", BNavbarNav);
Vue.component("b-dropdown-form", BDropdownForm);
Vue.component("b-form-radio", BFormRadio);
import "./styles/bootstrap/mystyles.scss";
export default {
install(Vue) {
Vue.component('my-navigation', MyNavigation);
},
};
export { MyNavigation };
and in package.json:
"main": "./dist/my-navigation.umd.js",
"module": "./dist/my-navigation.esm.js",
"unpkg": "./dist/my-navigation.min.js",
"files": [
"dist/*"
],
"dependencies": {
"core-js": "^3.3.2",
"vue": "^2.6.10"
},
"peerDependencies": {
"bootstrap-vue": "^2.0.4"
},
"scripts": {
"build-bundle": "vue-cli-service build --target lib --name my-navigation ./src/main-navbar.js"
},
I can of course work around this by importing the components directly in MyNavigation.vue, but I want to register them globally for use in another component I'll be including in the npm package as well; and well it just seems weird to me that it works through the registry but not locally
Edit: it appears that through the registry, the bootstrap-vue components are being registered globally and are available then in my-vue-app by importing the npm package. This seems like a bad idea(?), so I probably don't want that anyway.
npm pack produces a .tgz file https://docs.npmjs.com/cli/pack.html
Importing from this file instead of from dist has the same behaviour as importing from a package on the registry.
Still not sure why or what npm does in creating this file, but that answers at least the question of how to mimic the behaviour of a registered package when importing from local/a repository.

Running Mocha 6 ES6 tests with Babel 7, how to set up?

For a library written in ES6/7, I want to compile (to ES5) the library to a dist/ folder. I also want to run the tests (written in ES6/7) for this lib.
My dev dependencies look like this (package.json):
"devDependencies": {
"#babel/cli": "^7.4.4",
"#babel/core": "^7.4.5",
"#babel/preset-env": "^7.4.5",
"#babel/register": "^7.4.4",
"chai": "^4.2.0",
"mocha": "^6.1.4",
"sinon": "^7.3.2"
},
My build and test scripts looks like this (package.json):
"scripts": {
"test": "mocha --require #babel/register",
"build": "babel src -d dist --presets=#babel/preset-env"
},
Running npm run build works well. The dist/ folder gets populated with transpiled files.
Running npm run test does not seem to work - this is my problem.
> mocha --require #babel/register
/Users/dro/Repos/lib/node_modules/yargs/yargs.js:1163
else throw err
^
ReferenceError: regeneratorRuntime is not defined
Initially I got an import error, which was resolved by adding .babelrc file.
Below is my .babelrc file content.
{
"presets": ["#babel/preset-env"]
}
I was reading about regeneratorRuntime and it got me to this link about babel-polyfill where they explain I shouldn't need that polyfill.
This will emulate a full ES2015+ environment (no < Stage 4 proposals) and is intended to be used in an application rather than a library/tool.
What is needed to set this up properly?
I am not using webpack.
Testing in ES6 with Mocha and Babel 7. Look here: https://dev.to/bnorbertjs/my-nodejs-setup-mocha--chai-babel7-es6-43ei or http://jamesknelson.com/testing-in-es6-with-mocha-and-babel-6/
npm install --save #babel/runtime
npm install --save-dev #babel/plugin-transform-runtime
And, in .babelrc, add:
{
"presets": ["#babel/preset-env"],
"plugins": [
["#babel/transform-runtime"]
]
}
Look at the project documentation:
npm install --save-dev babel-register
In your package.json file make the following changes:
{
"scripts": {
"test": "mocha --require babel-register"
}
}
Some features will require a polyfill:
npm install --save-dev babel-polyfill
{
"scripts": {
"test": "mocha --require babel-polyfill --require babel-register"
}
}
Below steps are for applying Babel transformations & core-js polyfills for your tests file:
💡 All transformations are only done per current environment, so only what is needed to be transpiled/polyfilled, will be. Target environments may be defined from a .browserslist file or as a property in package.json file. (read more here)
Step 1: Install packages:
#babel/core (read why)
#babel/preset-env (read why)
#babel/register (read why)
core-js (read why)
Note that #babel/polyfill exists and uses core-js under the hood. However, it was deprecated in favor of using core-js directly.
Step 2: Create a Babel configuration file babel.config.js
(used to be .babelrc.js or a .json file).
Create this file at the root-level of your code.
The most basic configuration (for just testing and not bundling) would look like this:
module.exports = {
presets: [
['#babel/preset-env', {
"corejs": "3.26",
"useBuiltIns": "usage"
}],
};
corejs - This is the polyfills library and should be specified with the minor version, otherwise x.0 will be used.
It is needed when testing code on rather "old" Node versions, which do not support all of the language methods. This ofc depends on your own usage of such javascript methods. (for example String.prototype.replaceAll).
useBuiltIns - must be set in order for the corejs polyfills to be applied. Read about it in the official docs.
By default, #babel/preset-env will compile your code for the current environment, but you can specify a different environment by setting the "targets" option in the configuration.
Ofc, you can add more presets like #babel/preset-react for example, if your code it written in React, or any other plugins which are specifically needed for your code.
Step 3: Connect mocha to the babel configuration:
In your package.json file
Under the scripts section, simply write something like this:
"test": "mocha \"src/**/*.test.js\""
Create a .mocharc.json file with this content:
{
"exit": true,
"color": true,
"require": ["#babel/register"],
"ignore": "node_modules"
}
This will apply Babel transformations to all of your test files.
If you need need to apply some special global javascript before/to all of your tests, you can add another file to the require setting, for example, fixtures.cjs:
"require": ["#babel/register", "fixtures.cjs"],
fixtures.cjs:
Below example applies a chai (popular alongside Mocha) plugin for testing DOM-related code:
var chai = require('chai'),
chaiDOM = require('chai-dom');
// https://stackoverflow.com/questions/62255953/chai-usechaihttp-once-or-in-every-test-file
// https://mochajs.org/#global-teardown-fixtures
exports.mochaGlobalSetup = function () {
chai.use(chaiDOM);
}
Interesting reads:
Babel vs babel-core vs babel-runtime
How does mocha / babel transpile my test code on the fly?